Me, too. I spent about 2 years on writing and testing a small utility library which mainly consists of generic utility functions, generic algorithms and some useful small structs and macros for debugging purposes. The library heavily relies on use of various SFINAE techniques and tag dispatching. The reason I decided to write that library was to make interfacing with the C++ STL library a bit easier. In the end I learned a ton about generic programming and template metaprogramming.
This is awesome. As someone who really doesn't like just using auto everywhere because of type obscuring, I can't wait to be able to code in this style.
Hello Json. I really like your videos, they help me alot. May i request a video about std::to_chars floating point that msvc recently implemented in header ( C++17) . It kinda weird and i don't know how to use it well. Thank you, i appreciate your knowledges.
But if we replace returned "floating_point auto" with just int, we somehow require the returned value to be int. Although, in this case implicit casts are possible which is, I assume, you didn't want to discuss (probably doesn't make sense in this context as we don't want to have them at all).
Hey, is there a way to use concepts to help compiler in doing CTAD? I have a use case for FFT (Fast Fourier Transform) which either takes std::complex as T, or my custom class Modulo where MOD is of type uint64_t (Formally known as Number Theoretic Transform, but the algorithm is same). Currently, I am using template vector& FFT_internal(vector& a, bool invert=false); (I want to access MOD value whenever Modulo is used, and ignore MOD if std::complex is used). But I can't use FFT_internal(arr1) directly here, as I need to pass MOD and T explicitly. I am wondering if I can deduce MOD in constexpr context or in concepts
decltype(requires(){ requires requires(){ requires requires(){ requires true;};};}) myRequires() requires requires(){ requires requires() { requires requires() { requires requires(){ requires requires() { requires true; }; }; }; }; } { return requires(){ requires requires(){ requires true;};};} This is valid C++20 code that will compile. And it's just the tip of the iceberg as you could expand this indefinitely and turn the nesting--like in Set Theory--into a mathematical language.
It's just grammar rules which just don't prohibit it. Where is problem? C++ grammar summary for all cases is like 22 papers than for example C# has about 47 papers (just downloaded from learn microsoft) and so on.
Can someone say to me what Jason says here : ua-cam.com/video/dR64GQb4AGo/v-deo.html (at the end of the vidéo) after he says "SFINAE, concepts, ...." I hear "nature syntax", but I think he says another thing. thanks in advance
I wonder why you still need auto I guess it's there for the sake of adding multiple concepts to single variable, so why not to allow dropping auto when there's only one concept used?
The auto is a compromise so that people can glance at the declaration and tell it's a template without going and looking up whether the names are a concept or a type. The compiler could do it without that, and there was an earlier proposal to type `Concept param`, but there was a strong pushback over it being identical to a regular function declaration.
@@NoNameAtAll2 Concepts are rather templated predicates which accept or reject concrete types. You cannot have a variable of type floating_point because it is not a concrete type. By using a concept you express your intention that whatever type is deduced it will satisfy the concept but depending on parameter types to function 'go' the type of variable would be float, double or long double. You only tell the compiler you do not expect int or class etc. in this place and clang correctly reports an error when deduced type happens to be int
I've read most of the comments here. Here some people compare very conveniently for themselves one solution that checks some conditions at the compile time with code that doesn't (and can't). If we rightfully compare a similar code, we get just auto sum(auto a, auto b) { return a+b; }. Yeah, it's more simple than with generics in other languages. And these people somehow manage to make a bad opinion about the language in this situation. I'm just surprised how it's even possible to be so convenient (about some people here)
Hey Jason! Thanks for your excellent videos and tutorials. Do you see any possible pitfalls or gotchas with the features that are coming in? Something programmers should be aware of?
it seems like you should be able to write `floating_point val = go(1.2, 2.3f)`. I dont get why there has to be an auto in between if it already knows its a concept auto deduction.
As nice as it might be to be able to leave out the “auto” in concept-based declarations, the purpose of concepts is to *simplify* templated programming, not hide its existence completely.
I understand that "floating_point auto" boils down to "double" in this case. So const floating_point auto val = 1.2; becomes: const double val = 1.2; which is totally fine.
Is it me or the SFINAE version is actually way more readable? I dont get this obsession with abstract readability, it actually obscured a lot of the things that are going on underneath so how exactly is that more readable? More compact, sure, but not easier to understand the logic.
I think it's just you. I've never found SFINAE readable, and have used it off and on for more than 15 years. Plus, concepts work with overload resolution in a different way than SFINAE. It's still technically syntactic sugar, but the way that subsumption of rules is treated and the best overload is picked is quite a bit more complicated to do with SFINAE
I think that keyword auto is extra in this syntax: floating_point auto value = 0.0f; Personally, I would prefer it w/o auto at all. Just rely on the fact, that concept always describes a template type (by describing its constraints). I.e. floating_point value = 0.0f; It might produce naming conflicts with real types, but I think it would be a bad practice to name concepts and types the same.
Unless you're writing embedded code, there's almost no reason not to just write the concept version first. -*Maybe*. I'd still argue for concepts almost everywhere, even when you *do* want to use only a specific concrete type, just because it massively decouples definitions from their usage. Knowing how many bytes your floating type parameter uses doesn't help you to understand the algorithm that uses it, and limits future usage to the specific needs of the immediate purpose. I'd say write the concept version and write a `using` type alias for the one specialization you actually want, a la the standard's (equivalent to) `using string = basic_string;`
after a mere 40 years, cpp starts to look like, scratch that, work like a sane language. algebraic data types are not fully there, typeclasses are fully there not there, but at least it's something.
Hey Jason, text is too small in all your videos. I dont know about the others but it is almost impossible for me to see the code when watching with my smart phone.
Watch it on the desktop. This is a programming video, it's not meant to be seen correctly on mobile phone. Also, if it is seen correctly on the phone, it would be garbage on desktop, which is the platform one is using for programming, 99% of the time.
@@Swedishnbkongu Well there is no simple answer to your question. ;) Do you have some plan for it or just want to learn another programming language? On this world there are people that know 2 or more programming languages but they have never written a useful program, so if I can make a suggestion you should thing about that, I mean you should think about the reason you want to learn rust and if you can come up with something other than just pure knowledge about the language then go for it, in other cases I don't think there's much sense in this. ;) Sorry for my bad english btw :)
@@haI9k your English is fine, don't worry about it! I would be interested in learning rust, and if I decided I liked it more I'd definitely use it. My question is more wondering if I'll like it more than C++. The reason I mentioned that I'm already pretty far in C++ is because that's an important factor, I think given that I already know a lot of C++ I would like it more than a beginner. If it was a beginner I might recommend rust over C++ from what I gather, I just don't know if an intermediate-advanced C++ dev should make the switch
So they basically didn't fix there template mess but extended over it. Can i have a requires just with T == float || T == double? And they even made it more ambiguous how hilarious 🤣
NoName Sure you would only check pointer equally else like NSString also does. Here it's more a i don't see the point of making it so ugly and depending on a std library that relies on optimizations that are not mandatory by standard.
That alternative concept syntax is one of the dumbest things I've seen in a while, it doesn't even work properly, it behaves differently from the original syntax... people really just want to throw any old idea into the language nowadays...
I got pretty used to SFINAE, but damn, I won't miss it when it's gone!
Me, too. I spent about 2 years on writing and testing a small utility library which mainly consists of generic utility functions, generic algorithms and some useful small structs and macros for debugging purposes. The library heavily relies on use of various SFINAE techniques and tag dispatching. The reason I decided to write that library was to make interfacing with the C++ STL library a bit easier. In the end I learned a ton about generic programming and template metaprogramming.
A great, easy-to-follow intro to a concept (NPI) as always Jason. Thanks!
Thanks!
Thank you!
Just wanted to point out that if you check the "Wrap lines" checkbox, then you won't have to scroll right to see the full compiler output.
This is awesome. As someone who really doesn't like just using auto everywhere because of type obscuring, I can't wait to be able to code in this style.
Add more complexity to make something else simpler. C++ 2019
Please moar concepts!
I would expect customise error message, as for assert
Hello Jason. Thanks for sharing your knowledges and skills. I appreciate that #cpp #cplusplus
Hello Json. I really like your videos, they help me alot. May i request a video about std::to_chars floating point that msvc recently implemented in header ( C++17) . It kinda weird and i don't know how to use it well. Thank you, i appreciate your knowledges.
ua-cam.com/video/4P_kbF0EbZM/v-deo.html
floating_point auto value. Yuck !
What is this syntax called? Is Jason saying "tar syntax"? 🤔
@@edmondmovsisyan2224 he called "terse" meaning more short and concise syntax.
But if we replace returned "floating_point auto" with just int, we somehow require the returned value to be int. Although, in this case implicit casts are possible which is, I assume, you didn't want to discuss (probably doesn't make sense in this context as we don't want to have them at all).
Hey, is there a way to use concepts to help compiler in doing CTAD? I have a use case for FFT (Fast Fourier Transform) which either takes std::complex as T, or my custom class Modulo where MOD is of type uint64_t (Formally known as Number Theoretic Transform, but the algorithm is same).
Currently, I am using
template
vector& FFT_internal(vector& a, bool invert=false);
(I want to access MOD value whenever Modulo is used, and ignore MOD if std::complex is used). But I can't use FFT_internal(arr1) directly here, as I need to pass MOD and T explicitly. I am wondering if I can deduce MOD in constexpr context or in concepts
I think you want "deducing this" for this use case instead, but I haven't spent enough time with that to be sure.
I am not sure if 'deducing this' will apply here.. FFT_internal doesn't belong to any class
Do you know of a good example of doing this with variadic templates?
Add a request here, and I'll see what I can do: github.com/lefticus/cpp_weekly/issues
decltype(requires(){ requires requires(){ requires requires(){ requires true;};};}) myRequires() requires requires(){ requires requires() { requires requires() { requires requires(){ requires requires() { requires true; }; }; }; }; }
{ return requires(){ requires requires(){ requires true;};};}
This is valid C++20 code that will compile. And it's just the tip of the iceberg as you could expand this indefinitely and turn the nesting--like in Set Theory--into a mathematical language.
It's just grammar rules which just don't prohibit it. Where is problem? C++ grammar summary for all cases is like 22 papers than for example C# has about 47 papers (just downloaded from learn microsoft) and so on.
@@keshkek I mean I’m not saying it’s good or bad I’m just pointing out that this is a thing.
Can someone say to me what Jason says here : ua-cam.com/video/dR64GQb4AGo/v-deo.html (at the end of the vidéo) after he says "SFINAE, concepts, ...." I hear "nature syntax", but I think he says another thing. thanks in advance
Hi! It's very likely to be "the terse syntax" (he mentions it at 7:03 also)
I wonder why you still need auto
I guess it's there for the sake of adding multiple concepts to single variable, so why not to allow dropping auto when there's only one concept used?
I'm guessing it is so the compiler can distinguish between types and concepts
@@12affes but concepts are templated types?
The auto is a compromise so that people can glance at the declaration and tell it's a template without going and looking up whether the names are a concept or a type. The compiler could do it without that, and there was an earlier proposal to type `Concept param`, but there was a strong pushback over it being identical to a regular function declaration.
thanks, that explains it
@@NoNameAtAll2 Concepts are rather templated predicates which accept or reject concrete types. You cannot have a variable of type floating_point because it is not a concrete type. By using a concept you express your intention that whatever type is deduced it will satisfy the concept but depending on parameter types to function 'go' the type of variable would be float, double or long double. You only tell the compiler you do not expect int or class etc. in this place and clang correctly reports an error when deduced type happens to be int
Can you recommend a good C++ or general programming book for a beginner?
@Mohsan Ali Thanks Mohsan!
I've read most of the comments here. Here some people compare very conveniently for themselves one solution that checks some conditions at the compile time with code that doesn't (and can't). If we rightfully compare a similar code, we get just auto sum(auto a, auto b) { return a+b; }. Yeah, it's more simple than with generics in other languages. And these people somehow manage to make a bad opinion about the language in this situation. I'm just surprised how it's even possible to be so convenient (about some people here)
Hey Jason! Thanks for your excellent videos and tutorials.
Do you see any possible pitfalls or gotchas with the features that are coming in? Something programmers should be aware of?
it seems like you should be able to write `floating_point val = go(1.2, 2.3f)`. I dont get why there has to be an auto in between if it already knows its a concept auto deduction.
As nice as it might be to be able to leave out the “auto” in concept-based declarations, the purpose of concepts is to *simplify* templated programming, not hide its existence completely.
Hello. Why is this possible:
const floating_point auto val = 1.2;
Here the const referes to the concept? Why does this work?
I understand that "floating_point auto" boils down to "double" in this case. So
const floating_point auto val = 1.2;
becomes:
const double val = 1.2;
which is totally fine.
@@user-user.user-user Oh, yes. This makes sence. When it first boids down and then the const is applied. Thx.
The code:
godbolt.org/z/eKFD2s
I think that static_assert does the job if it comes to input variables. You can specify what message the programmer sees on the wrong input.
static_assert comes after overload resolution. SFINAE and constraints block the given function from being a candidate.
thank god
Thank you very much for explaining all of this! Concepts seems quite readable indeed, but I would not to like to see this terse syntax in the code.
I'd prefer to make it is_convertible to float or double or long double.
Is it me or the SFINAE version is actually way more readable? I dont get this obsession with abstract readability, it actually obscured a lot of the things that are going on underneath so how exactly is that more readable? More compact, sure, but not easier to understand the logic.
I think it's just you. I've never found SFINAE readable, and have used it off and on for more than 15 years.
Plus, concepts work with overload resolution in a different way than SFINAE. It's still technically syntactic sugar, but the way that subsumption of rules is treated and the best overload is picked is quite a bit more complicated to do with SFINAE
I think that keyword auto is extra in this syntax: floating_point auto value = 0.0f; Personally, I would prefer it w/o auto at all. Just rely on the fact, that concept always describes a template type (by describing its constraints). I.e. floating_point value = 0.0f; It might produce naming conflicts with real types, but I think it would be a bad practice to name concepts and types the same.
I know this is a toy example, but I can't help thinking 'at what point do you just make the types floats' :)
@Avander Dagunwouldn't you just use explicit in that case?
Unless you're writing embedded code, there's almost no reason not to just write the concept version first.
-*Maybe*. I'd still argue for concepts almost everywhere, even when you *do* want to use only a specific concrete type, just because it massively decouples definitions from their usage. Knowing how many bytes your floating type parameter uses doesn't help you to understand the algorithm that uses it, and limits future usage to the specific needs of the immediate purpose.
I'd say write the concept version and write a `using` type alias for the one specialization you actually want, a la the standard's (equivalent to) `using string = basic_string;`
after a mere 40 years, cpp starts to look like, scratch that, work like a sane language. algebraic data types are not fully there, typeclasses are fully there not there, but at least it's something.
Hey Jason, text is too small in all your videos. I dont know about the others but it is almost impossible for me to see the code when watching with my smart phone.
Watch it on the desktop. This is a programming video, it's not meant to be seen correctly on mobile phone. Also, if it is seen correctly on the phone, it would be garbage on desktop, which is the platform one is using for programming, 99% of the time.
Spend an hour writing a function that adds two numbers together.
Poor west const is middle const
Syntax is as always with c++ messy, in rust if I remember correctly they have clause and much cleaner syntax but maybe I am wrong. ;)
Should I learn rust? I have already diven moderately deep into C++ but am sometimes curious about rust (surely it isn't as complex)
@@Swedishnbkongu Well there is no simple answer to your question. ;) Do you have some plan for it or just want to learn another programming language? On this world there are people that know 2 or more programming languages but they have never written a useful program, so if I can make a suggestion you should thing about that, I mean you should think about the reason you want to learn rust and if you can come up with something other than just pure knowledge about the language then go for it, in other cases I don't think there's much sense in this. ;)
Sorry for my bad english btw :)
@@haI9k your English is fine, don't worry about it! I would be interested in learning rust, and if I decided I liked it more I'd definitely use it. My question is more wondering if I'll like it more than C++. The reason I mentioned that I'm already pretty far in C++ is because that's an important factor, I think given that I already know a lot of C++ I would like it more than a beginner. If it was a beginner I might recommend rust over C++ from what I gather, I just don't know if an intermediate-advanced C++ dev should make the switch
#Eastconst!
East-const does seem more logical in this context
#WestConst
#NorthConst
How about doing something like this?
static_assert(std::is_same::value,
"Wrong type; must be a float.");
Then you can’t use it with double or long double
I really don't think the auto is necessary. They should remove the requirement to use it immediately.
C++ has gone too far
😂😂😂😂
That's what C++ """critics""" have been saying ever since C++ dared to be C with classes, so your point is moot, cope
I appreciate it, but what are they doing to C++?! I get it though, but still... it’s not a scripting language
So they basically didn't fix there template mess but extended over it. Can i have a requires just with T == float || T == double?
And they even made it more ambiguous how hilarious 🤣
You can, but you would need to use std::is_same || std::is_same instead
That's not a option also it still looks ugly compared to == it's like javas and objc's string.equals.
@@platin2148 string.equals is runtime check
NoName Sure you would only check pointer equally else like NSString also does. Here it's more a i don't see the point of making it so ugly and depending on a std library that relies on optimizations that are not mandatory by standard.
@@platin2148 What do you mean 'That's not a option'?
== is for comparing expressions, not types.
That alternative concept syntax is one of the dumbest things I've seen in a while, it doesn't even work properly, it behaves differently from the original syntax... people really just want to throw any old idea into the language nowadays...
Or... you know... do it like Java or C# do it
Yeah....they don't.
Try deriving from a generic type parameter
class Base : T
or
class Base extends T