This is the best presentation, I have seen on cppcon. It is very obvious that the speaker put a lot of effort for preparing this presentation. Timing, design of content, slides, examples chosen just excellent.
Words cannot describe how useful, interesting and enlightening this talk is. As someone in the audience said at the end of the second part, you really really rock sir Brown 😊 Thank you and congrats
great speaker! pauses at the right places and all, not hyperactive. clean slides, to the point. subject is so interesting and very well introduced when you're not a TMP wiz.
Producing such a collection of slides requires a tremendous amount of effort and knowledge, similar to writing a research paper. I admire Mr. Brown's work.
That was truly mind-blowing. (while listening to the talk, I am coming to a conclusion, that...) Despite knowing everything about C++, I didn't know anything.
Amazing job, Walter. The last CppCon talk I watched was from the STL guy. I think his slides were smart but I can't really tell because I couldn't follow. But I grasped everything here. Very intuitive and crisp presentation. Thank you so much
Quick summary: templates were originally meant for use. eg: template struct Blah {...}; // The template seems pointless if you don't use it However, with SFINAE we can use our templates to perform checks: template struct Blah {...}; // Now we make sure that T is default constructible. // This can still make sense even if we don't use S (FYI, because of this, we don't have to give S a name): template struct Blah {...}; So Dr. Brown suggests that its better to throw all of these expressions (where we only care about their validity, and not their evaluated type) into one place (a kind of "black hole"), void_t: template using void_t = void; // He had to implement it in a slightly // more awkward way for clang So if you call it: void_t; Then it checks the validity of the expressions: if all are valid, it returns void, if not, it's SFINAE-ed out. The fact that it has a single and predictable return type is key to its usefulness. As I understand it, that's the purpose of the presentation: to introduce this little tool and show that it's useful. FYI it's now part of the standard library with his suggested name. ************** Now, if someone could help me *********** What is the aim of the code on slides 34/35 (in part II)? His wording here seems super confusing. Is he looking for: 1. Whether T has a member named "type" (where, confusingly, we don't care about its type) 1. --> this option seems the most obvious, except that his code won't compile because of the line 'typename T::type', because 'type' doesn't name a type. 2. Whether T has a member of a certain 'type', but we don't care about its name. 2. --> Again, this won't compile at the same line (expected identifier before 'type') 3. Whether T has an inner type (eg. class/struct/enum declared within it)? 3. --> this compiles and performs the check correctly, but has nothing to do with members of T, so doesn't make sense to me in the context of his presentation. Did he mean to write: struct has_type_member< T,void_t< decltype( T::member ) > > : true_type { }; instead of: struct has_type_member< T,void_t< typename T::member > > : true_type { }; ? This would make 1. work....
Clear explanations though many aspects are probably familiar for someone who has survived the Boost.Mpl documentation. I think it's also an improvement to drop the required comment in static_assert, although the use cases shown in the video could have benefit from some extra explanatory text. The modern aspects are handled in part 2.
40:00 I had a couple of questions about it, for a long time. - How the unnamed struct will be declared, if it inherits from another class/struct? - and how the CRTP will be handled in unnamed struct/class?
Why can we write something like this instead of specialization ? I got compilation issue but appears valid for me static int constexpr value = (N == 0) ? M : gcd::value; // ignoring M != 0 static assert for this case.
This took me a couple minutes to work out, so I figured I'd write it out here. template // non-array (also base case to exit recursion) struct rank { static const size_t value = 0u; } template struct rank { static const size_t value = 1u + rank::value; } Lets say you pass in int[10][20] First iteration, U == int[10], N == 20, expanded with U in parens: struct rank { static const size_t value = 1u + rank:: value; } Second iteration, U == int, N == 10, expanded with U in parens: struct rank { static const size_t value = 1u + rank::value; } Note that rank matches the 0 value base-case, so you end up getting (all expanded inline): struct rank { static const size_t value = 1u + 1u + 0; } The mechanism to erase dimensions is just how the typename U always has to have one fewer dimension than the full type in the struct part since the struct is U[N], so when you pass in int[10][20], U has to be int[10] in order for U[N] to match anything (and in this case, N == 20). Each time you call/recurse into the metafunction, you're calling it with the current U, and the same dimension "erasing" (there's probably a technical name for this...) occurs each time. I hope this makes sense and isn't too poorly worded. In terms of " from int[10][20][30] to int[20][30] then to int[30]?" -- well it goes in the opposite direction. You go from int[10][20][30] to int[10][20] to int[10] to int.
what is the difference between first version and second version of compile time evaluated pow functions v1 and v2 why is there such a big difference in performance
We have a big hint given the time complexity of the algorithms. V1 ran in linear time and we deduce that it is simply using repeated multiplication. V2 ran in logarithm time thus we deduce that it is using a recursive scheme to compute the powers. x^8, for example, can be computed with 8 multiplications or x^8 = (x^4)(x^4) = (x^2)^4 which amounts to 5 multiplications
Well, if you define computer science and computational science [which ( in the theoretical domain {at least}) it is] then yes all math is necessarily computer science.
Yet you think it appropriate to comment without either listening to or understanding his point (delete as applicable). That point being that template metaprogramming has been a usable optimisation for nearly 15 years now. Perhaps were you trying to be funny?
15:34 The word _weird_ does not mean _unfamiliar._ The former has an objective meaning at least to some degree, but _unfamiliar_ is entirely subjective by definition. You can familiarize with something weird, which in some meaning makes it non-weird to you, but in others, the thing stays weird if it’s generally agreed upon to be weird.
Why UA-cam delete my comments when I tell the the truth: C/C++ is best algorithmics and mathematical language. I hope this will stay. First time I don't understand nothing just someone speaking alien language, So I go to Bjarne book for templates and return back here and two times and I start 💡
54:40 std::integral_constant is a joke because it can take any type and value suitable as a template argument. It’s _not_ - as the name suggests - restricted to integral types.
I think you and the likers of your statement didn't get the key message. It was not about a quantitative comparison, but a qualitative comparison. The absolute numbers may be different on current computers, but the relative comparison remains the same. I know it's hard to understand, but that doesn't make it any less real.
This is the best presentation, I have seen on cppcon. It is very obvious that the speaker put a lot of effort for preparing this presentation. Timing, design of content, slides, examples chosen just excellent.
Words cannot describe how useful, interesting and enlightening this talk is.
As someone in the audience said at the end of the second part, you really really rock sir Brown 😊
Thank you and congrats
Glad it was helpful!
It is simply mind-boggling, the way his guy makes this really weird subject become understandable.
Yeah...
great speaker! pauses at the right places and all, not hyperactive. clean slides, to the point. subject is so interesting and very well introduced when you're not a TMP wiz.
Loved the Borland Turbo C++ color scheme.
Producing such a collection of slides requires a tremendous amount of effort and knowledge, similar to writing a research paper. I admire Mr. Brown's work.
This is a magnificent lecture. Thank you Walter E. Brown for the execellent presentation and teaching!
"Mathematics is after all just a small branch of Computer Science". That is now my favorite quote of all time.
Luca Sas so spot on
actually its big
"Computer Science is after all just a small branch of Mathematics". There, I corrected you.
This is an amazing introduction for Template Metaprogramming. It's too late I reached here, but still worth the knowledge.
That was truly mind-blowing.
(while listening to the talk, I am coming to a conclusion, that...)
Despite knowing everything about C++, I didn't know anything.
C++ is the The Beast.. There's a 1001 dark and dusty corners and Scheherazade is waiting there with dragons upon dragons to roast you.
Template metaprogramming is fun. Well only after I watched Mr Walter talks.
Amazing job, Walter. The last CppCon talk I watched was from the STL guy. I think his slides were smart but I can't really tell because I couldn't follow. But I grasped everything here. Very intuitive and crisp presentation. Thank you so much
Absolutely stellar talk as usual from Dr. Brown!
Is there another recording out there with better audio quality? It got pretty crispy in some parts.
Quick summary:
templates were originally meant for use.
eg:
template
struct Blah {...}; // The template seems pointless if you don't use it
However, with SFINAE we can use our templates to perform checks:
template
struct Blah {...}; // Now we make sure that T is default constructible.
// This can still make sense even if we don't use S
(FYI, because of this, we don't have to give S a name):
template
struct Blah {...};
So Dr. Brown suggests that its better to throw all of these expressions
(where we only care about their validity, and not their evaluated type)
into one place (a kind of "black hole"), void_t:
template
using void_t = void; // He had to implement it in a slightly
// more awkward way for clang
So if you call it:
void_t;
Then it checks the validity of the expressions:
if all are valid, it returns void,
if not, it's SFINAE-ed out.
The fact that it has a single and predictable return type is key to its
usefulness.
As I understand it, that's the purpose of the presentation: to introduce
this little tool and show that it's useful. FYI it's now part of the
standard library with his suggested name.
************** Now, if someone could help me ***********
What is the aim of the code on slides 34/35 (in part II)?
His wording here seems super confusing. Is he looking for:
1. Whether T has a member named "type" (where, confusingly, we don't
care about its type)
1. --> this option seems the most obvious, except that his code won't
compile because of the line 'typename T::type', because 'type' doesn't
name a type.
2. Whether T has a member of a certain 'type', but we don't care about
its name.
2. --> Again, this won't compile at the same line (expected
identifier before 'type')
3. Whether T has an inner type (eg. class/struct/enum declared within
it)?
3. --> this compiles and performs the check correctly, but has
nothing to do with members of T, so doesn't make sense to me in the
context of his presentation.
Did he mean to write:
struct has_type_member< T,void_t< decltype( T::member ) > > : true_type
{ };
instead of:
struct has_type_member< T,void_t< typename T::member > > : true_type
{ };
? This would make 1. work....
Clear explanations though many aspects are probably familiar for someone who has survived the Boost.Mpl documentation. I think it's also an improvement to drop the required comment in static_assert, although the use cases shown in the video could have benefit from some extra explanatory text.
The modern aspects are handled in part 2.
Dr Brown performs like G. This is mind expanding stuff !!!
I finally understand what SFINAE actually means now thank you
40:00 I had a couple of questions about it, for a long time.
- How the unnamed struct will be declared, if it inherits from another class/struct?
- and how the CRTP will be handled in unnamed struct/class?
That was indeed a great talk!
This is a great, great talk.
Great talk, thank you
This is just mind-blowing.
An excellent presentation. I also recommend the following book for meta programming fundamentals : Modern C++ Design : Andrei Alexandrescu
53:00 Concepts are in C++20, and it looks like this:
template
maxint_t f(T val) { … }
Programs writing programs... Wow!
Awesome talk;
Never knew that static_assert statement can be used inside a struct! (16:00)
It works because static_assert counts as a declaration that doesnt create a name
Why can we write something like this instead of specialization ? I got compilation issue but appears valid for me
static int constexpr value = (N == 0) ? M : gcd::value; // ignoring M != 0 static assert for this case.
wow, great talk!
14:58 As of C++20, virtual functions can be constexpr.
I'm impressed....... Very!
Slide 14, 1u + rank::value, how is it iterating to next array say from int[10][20][30] to int[20][30] then to int[30]?
This took me a couple minutes to work out, so I figured I'd write it out here.
template // non-array (also base case to exit recursion)
struct rank { static const size_t value = 0u; }
template
struct rank {
static const size_t value = 1u + rank::value;
}
Lets say you pass in int[10][20]
First iteration, U == int[10], N == 20, expanded with U in parens:
struct rank {
static const size_t value = 1u + rank:: value;
}
Second iteration, U == int, N == 10, expanded with U in parens:
struct rank {
static const size_t value = 1u + rank::value;
}
Note that rank matches the 0 value base-case, so you end up getting (all expanded inline):
struct rank {
static const size_t value = 1u + 1u + 0;
}
The mechanism to erase dimensions is just how the typename U always has to have one fewer dimension than the full type in the struct part since the struct is U[N], so when you pass in int[10][20], U has to be int[10] in order for U[N] to match anything (and in this case, N == 20). Each time you call/recurse into the metafunction, you're calling it with the current U, and the same dimension "erasing" (there's probably a technical name for this...) occurs each time. I hope this makes sense and isn't too poorly worded.
In terms of " from int[10][20][30] to int[20][30] then to int[30]?" -- well it goes in the opposite direction. You go from int[10][20][30] to int[10][20] to int[10] to int.
this was the thing I was confused with thanks for asking and thanks @Ulchie for explaining.
Is this the person you mentioned? EMMY NOETHER
Awesome!!!
He wrote a template to generate newer charts, but it's still compiling. But when it's done, it's sooo gonna be so fast.
Great talk, though you could get a better mic for about 10 dollars
I dont see any issue with the sound
what is the difference between first version and second version of compile time evaluated pow functions v1 and v2 why is there such a big difference in performance
We have a big hint given the time complexity of the algorithms. V1 ran in linear time and we deduce that it is simply using repeated multiplication. V2 ran in logarithm time thus we deduce that it is using a recursive scheme to compute the powers. x^8, for example, can be computed with 8 multiplications or x^8 = (x^4)(x^4) = (x^2)^4 which amounts to 5 multiplications
Well, if you define computer science and computational science [which ( in the theoretical domain {at least}) it is] then yes all math is necessarily computer science.
but not all math is about computation
Yet you think it appropriate to comment without either listening to or understanding his point (delete as applicable). That point being that template metaprogramming has been a usable optimisation for nearly 15 years now. Perhaps were you trying to be funny?
15:34 The word _weird_ does not mean _unfamiliar._ The former has an objective meaning at least to some degree, but _unfamiliar_ is entirely subjective by definition. You can familiarize with something weird, which in some meaning makes it non-weird to you, but in others, the thing stays weird if it’s generally agreed upon to be weird.
It drives me insane when the camera is following a presenter when he is discussing a slide and you have NO IDEA what he's referencing
32:20 That iterator_traits has no member named _type_ is actually good. It’s akin to a std::tuple not implicitly converting to its index-0 component.
This talk is totally nuts.
Why UA-cam delete my comments when I tell the the truth: C/C++ is best algorithmics and mathematical language. I hope this will stay.
First time I don't understand nothing just someone speaking alien language,
So I go to Bjarne book for templates and return back here and two times and I start 💡
54:40 std::integral_constant is a joke because it can take any type and value suitable as a template argument. It’s _not_ - as the name suggests - restricted to integral types.
Isn't it because that before C++20, template non-type parameters could only be integral, enum or pointer types?
Tom Hanks :P
META
perl...
I hate to type too.
underscore T syntax reminds me of perk. yuck.
Fast forward to 2017... and still concepts lite isn't a standard
If this is the only thing you took away from this talk, then I suggest you to watch something like "best fails 2015"... What a stupid comment!
Seriously? You dare to present charts and benchmarks from 2001 in a 2014 talk about "modern" Template Metaprogramming? How lazy can you get?
I think you and the likers of your statement didn't get the key message. It was not about a quantitative comparison, but a qualitative comparison. The absolute numbers may be different on current computers, but the relative comparison remains the same.
I know it's hard to understand, but that doesn't make it any less real.