Would have been much more informative if not for those (many!) instances where someone from the audience would talk for an extended period of time only for the presenter to then say "Thank you for that explanation" and moving on to next topic, leaving us, the viewers, guessing as to what was explained?.. In short: if you would like to have a pleasant experience watching this video - skip ALL(!) of the Q&A
Great talk ! I think important to distinguish between value and ‘trendy’. On the topic of polymorphism (58:31) note that ‘deducing this’ isn’t a full-replacement for CRTP, and there are situations where we’ll need CRTP (for example if the CRTP “base” has a member variable dependent on the ‘derived’ class
About the Singleton subject (I just reached 27') : One advantage of the DI solution that was not mentionned is that it makes explicit for the user-code what the lifetime of the Plotting object is, which leads to solving the issue where all other solutions don't guarantee an order of destruction because the object is global (static init/destruction failure) and not bound to the scope of `main()`. Unfortunately most singletons do complicated stuffs (otherwise they would not need to be singletons) so often the issue is that making sure the scope of `main()` is respected resource and logic -wise is made impossible by singletons. This is made worse when the singletons are provided by libraries instead of the end-user (the application). With DI, suddenly it's the application code that can decide if that object lifetime should or not be scoped in `main()`, or as a global in some well chosen translation unit. Essentially: libraries (yes even logging libraries) should never force singletons. Of course there are exceptions: one pattern I like is when a library cannot function without having access to a global object (like with logging) but doesnt handle itself the lifetime of that object. Instead the library provide a way to set that object after construction to make it available globally (through some setter function similar to how `set_terminate_handler` works I guess). That means the end-user code decides how to construct the object, it's lifetime, and is in control of when to start sharing it with the library. The pointer storage to that object needs to be global-static but the lifetime issue disappear.
Yeah sometimes singletons are fine, but in general in C++ i have rarely seen global singletons that were a problem.... now that i am mostly working in C# - darn do i hate them.
Good topics - thank you for posting these talks! Discussion-style presentations are interesting but lose much value if audience cannot be easily heard in the recording. A mic for audience participation or having the speaker repeat questions and comments would be greatly appreciated!
Deducing this has the same problem as CRTP if you pass the Session object to a function which takes a Tcp&. It will then deduce "self" as a "Tcp&" and also invoke the Tcp functions. Neither of the two approaches are a true replacement for runtime polymorphism. If you need that then Session/Tcp/Udp still need to be wrapped inside something that does the runtime dispatch (for example std::variant)
CRTP is compile-time polymorphism. It can only replace patterns where all information is known at compile time. It cannot provide runtime polymorphism by definition
There is a principle I am seeing ignored when talking about the singleton. We should try to make the dependencies as visible as possible, this means, dependencies should be stated ideally in declarative manner. That is, in the interface. Either being passed in or returned or kept. Dependencies on singletons are always in imperative code, which is more hidden. The DI approach is really better for testability, but who says you can't use both? You can pass a plotter that uses a singleton, or another one that's a mock or fake for testing.
It seems the audience was intrigued that monostate singleton approach hides the fact that a singleton is involved. But each function that internally uses a singleton also hides this implementation details. And this of course is the reason singletons are considered evil in the first place.
CRTP and 'deducing this' seem to require the code that calls the function in the examples to reference the type declaration of the derived class. This is a critical problem when your derived classes are layered components within an object that talk back and forth with each other, and/or multiple instances of the objects themselves talk back and forth with each other. It seems at least one side of the interface between them has to use virtual functions.
Can someone explain why the NTTP way of doing SFINAE is preferred? I couldn't quite understand the discussion as to why `enable_if_t = true` is preferred over `typename = enable_if_t`.
1. Default template parameters are not part of the function signature. Two signatures with `typename = enable_if_t` can result in a redefinition error, preventing simple overloads. Cppreference talks about this in the Notes for `std::enable_if`. 2. `enable_if_t = true` actually removes the function from the set of candidate overloads by not providing a `typedef`, which is why you're using `enable_if_t`. When the conditional of `enable_if` is false, there is no typedef resulting in an actual substitution failure. 3. template
Wrt. using SFINAE to limit the types your function accepts, I have had better luck using static asserts. You can put a big fat error message doing something like static_assert(std::is_arithmetic_v, "*** TIME PARAMETERS MUST BE ARITHMETIC TYPES ***") This will be much easier for users to spot in the error message output than a failed overload resolution. I reckon concepts could do this as well, but unfortunately, I'm stuck in a C++14 codebase :(
Wow never seen such use of "deducing this" yet. But anyway it kinda seem like a wrong/dangerous thing to use as CRTP replacement. I'd rather think about some kind of "self" alias in class to just remove nasty static casts everywhere and go with default CRTP approach
A note to video engineer(s): it is VERY hard to follow the conversation when you can't hear half of it :(
Would have been much more informative if not for those (many!) instances where someone from the audience would talk for an extended period of time only for the presenter to then say "Thank you for that explanation" and moving on to next topic, leaving us, the viewers, guessing as to what was explained?.. In short: if you would like to have a pleasant experience watching this video - skip ALL(!) of the Q&A
There is a thing called subtitle. Turn it on boy
@@mgnishibuya1 The auto generated subtitles are trash, I expect a conference of this caliber to get such a basic thing right.
Great talk ! I think important to distinguish between value and ‘trendy’.
On the topic of polymorphism (58:31) note that ‘deducing this’ isn’t a full-replacement for CRTP, and there are situations where we’ll need CRTP (for example if the CRTP “base” has a member variable dependent on the ‘derived’ class
About the Singleton subject (I just reached 27') : One advantage of the DI solution that was not mentionned is that it makes explicit for the user-code what the lifetime of the Plotting object is, which leads to solving the issue where all other solutions don't guarantee an order of destruction because the object is global (static init/destruction failure) and not bound to the scope of `main()`. Unfortunately most singletons do complicated stuffs (otherwise they would not need to be singletons) so often the issue is that making sure the scope of `main()` is respected resource and logic -wise is made impossible by singletons. This is made worse when the singletons are provided by libraries instead of the end-user (the application).
With DI, suddenly it's the application code that can decide if that object lifetime should or not be scoped in `main()`, or as a global in some well chosen translation unit. Essentially: libraries (yes even logging libraries) should never force singletons. Of course there are exceptions: one pattern I like is when a library cannot function without having access to a global object (like with logging) but doesnt handle itself the lifetime of that object. Instead the library provide a way to set that object after construction to make it available globally (through some setter function similar to how `set_terminate_handler` works I guess). That means the end-user code decides how to construct the object, it's lifetime, and is in control of when to start sharing it with the library. The pointer storage to that object needs to be global-static but the lifetime issue disappear.
Yeah sometimes singletons are fine, but in general in C++ i have rarely seen global singletons that were a problem.... now that i am mostly working in C# - darn do i hate them.
The way the topics were approached was very clever. Awesome talk!
Your comments are much appreciated, thank you!
Good topics - thank you for posting these talks! Discussion-style presentations are interesting but lose much value if audience cannot be easily heard in the recording. A mic for audience participation or having the speaker repeat questions and comments would be greatly appreciated!
Deducing this has the same problem as CRTP if you pass the Session object to a function which takes a Tcp&. It will then deduce "self" as a "Tcp&" and also invoke the Tcp functions. Neither of the two approaches are a true replacement for runtime polymorphism. If you need that then Session/Tcp/Udp still need to be wrapped inside something that does the runtime dispatch (for example std::variant)
CRTP is compile-time polymorphism. It can only replace patterns where all information is known at compile time. It cannot provide runtime polymorphism by definition
Very interesting topic. Comprehensively covered
There is a principle I am seeing ignored when talking about the singleton. We should try to make the dependencies as visible as possible, this means, dependencies should be stated ideally in declarative manner. That is, in the interface. Either being passed in or returned or kept. Dependencies on singletons are always in imperative code, which is more hidden.
The DI approach is really better for testability, but who says you can't use both? You can pass a plotter that uses a singleton, or another one that's a mock or fake for testing.
It seems the audience was intrigued that monostate singleton approach hides the fact that a singleton is involved. But each function that internally uses a singleton also hides this implementation details. And this of course is the reason singletons are considered evil in the first place.
Super interesting talk. Exactly the topic I was hoping someone would discuss.
CRTP and 'deducing this' seem to require the code that calls the function in the examples to reference the type declaration of the derived class. This is a critical problem when your derived classes are layered components within an object that talk back and forth with each other, and/or multiple instances of the objects themselves talk back and forth with each other. It seems at least one side of the interface between them has to use virtual functions.
Can someone explain why the NTTP way of doing SFINAE is preferred? I couldn't quite understand the discussion as to why `enable_if_t = true` is preferred over `typename = enable_if_t`.
1. Default template parameters are not part of the function signature. Two signatures with `typename = enable_if_t` can result in a redefinition error, preventing simple overloads. Cppreference talks about this in the Notes for `std::enable_if`.
2. `enable_if_t = true` actually removes the function from the set of candidate overloads by not providing a `typedef`, which is why you're using `enable_if_t`. When the conditional of `enable_if` is false, there is no typedef resulting in an actual substitution failure.
3. template
Thanks for sharing ! It would help if the audience had access to a microphone. It's hard to understand what they are saying
Wrt. using SFINAE to limit the types your function accepts, I have had better luck using static asserts.
You can put a big fat error message doing something like static_assert(std::is_arithmetic_v, "*** TIME PARAMETERS MUST BE ARITHMETIC TYPES ***")
This will be much easier for users to spot in the error message output than a failed overload resolution.
I reckon concepts could do this as well, but unfortunately, I'm stuck in a C++14 codebase :(
Ha, ha. Just noticed one of the audience members saying exactly what I just said... Maybe I should have watched the entire video before commenting :D
Im in a 2003 codebase and my software architect sees no problem in it
Would have been helpful if they had passed around a mic for the crowd lol
DI part should also probably mention ua-cam.com/video/BYpcAEfG3mo/v-deo.html although TBH I presume 98+% of C++ devs never heard of this.
Wow never seen such use of "deducing this" yet. But anyway it kinda seem like a wrong/dangerous thing to use as CRTP replacement. I'd rather think about some kind of "self" alias in class to just remove nasty static casts everywhere and go with default CRTP approach
I really liked this talk
I would say that the current fad is functional programming
kuhl
yeahp