C++20 Concepts: The Definitive Guide
31–40 of 102 posts
Re: C++20 Concepts: The Definitive Guide
#32Is this a scrappy version of type classes (Haskell) or traits (Rust)?
A significant difference in my understanding is that type classes and traits are required, but concepts are not. That is, using the example from the article, a concept can tell you if you're passing something that doesn't add, but you can add inside a function without using a concept. In other words:
fn add(x: T, y: T) -> T {
x + y
}
This won't compile in Rust: error[E0369]: cannot add `T` to `T`
--> src/lib.rs:2:7
|
2 | x + y
| - ^ - T
| |
| T
|
help: consider restricting type parameter `T`
|
1 | fn add>(x: T, y: T) -> T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
This suggestion works, but you don't have to write it this way. Once the constraints get more complex than T: Foo, I personally switch to this form: use std::ops::Add;
fn add(x: T, y: T) -> T
where
T: Add,
{
x + y
}
I find it a little easier to read. YMMV.Whereas in C++, this does compile:
template
T add(T a, T b)
{
return a + b;
}
If you try to add something that doesn't have + defined: int main(void) {
add("4", "5");
}
you get this :4:12: error: invalid operands to binary expression ('const char *' and 'const char *')
return a + b;
~ ^ ~
:8:5: note: in instantiation of function template specialization 'add' requested here
add("4", "5");
^
Whereas, if you do what the article does (though I'm using char* instead of std::string, whatever) #include
template
concept integral = std::is_integral_v;
template
T add(T a, T b)
{
return a + b;
}
int main(void) {
add("4", "5");
}
you get :12:5: error: no matching function for call to 'add'
add("4", "5");
^~~
:6:3: note: candidate template ignored: constraints not satisfied [with T = const char *]
T add(T a, T b)
^
:5:15: note: because 'const char *' does not satisfy 'integral'
template
^
/opt/compiler-explorer/gcc-11.1.0/lib/gcc/x86_64-linux-gnu/11.1.0/../../../../include/c++/11.1.0/concepts:102:24: note: because 'is_integral_v' evaluated to false
concept integral = is_integral_v;
^
This doesn't feel like a huge change because add is such a small function, but if it were larger and more complicated, the error with a concept is significantly better.Re: C++20 Concepts: The Definitive Guide
#33I feel like one of the things a "Definitive Guide" to this feature needs to make clear, and maybe even emphasise, is a key way these are different than say Rust type Traits. Concepts, just like the SFINAE and constrexpr hacks you should discard in their favour, are about only what will compile and you, the C++ programmer, are always responsible for shouldering the burden of deciding whether that will do what you mean…
Are you sure about this? In my tests floating points are always considered partially ordered, not totally ordered. This page [0] even mentions this in the notes towards the bottom. [0]: https://en.cppreference.com/w/cpp/utility/compare/partial_or...
Specifically these ordering classes are the result of the spaceship operator and the concept doesn't care whether you have a spaceship operator.
Re: C++20 Concepts: The Definitive Guide
#34I feel like one of the things a "Definitive Guide" to this feature needs to make clear, and maybe even emphasise, is a key way these are different than say Rust type Traits. Concepts, just like the SFINAE and constrexpr hacks you should discard in their favour, are about only what will compile and you, the C++ programmer, are always responsible for shouldering the burden of deciding whether that will do what you mean…
Re: C++20 Concepts: The Definitive Guide
#35I feel like one of the things a "Definitive Guide" to this feature needs to make clear, and maybe even emphasise, is a key way these are different than say Rust type Traits. Concepts, just like the SFINAE and constrexpr hacks you should discard in their favour, are about only what will compile and you, the C++ programmer, are always responsible for shouldering the burden of deciding whether that will do what you mean…
How can floats be totally ordered. This isn’t even a matter of NaNs or not. A set of floats where two or more floats compare equal does not permit a total ordering.
Re: C++20 Concepts: The Definitive Guide
#36Another language-changing paradigm added to C++. I haven't even finished learning the old ones yet. Sometimes I think C++ would be better off if the committee stopped accepting proposals that add new features.
Re: C++20 Concepts: The Definitive Guide
#37Another language-changing paradigm added to C++. I haven't even finished learning the old ones yet. Sometimes I think C++ would be better off if the committee stopped accepting proposals that add new features.
First, you don't have to use the new features (though eventually you'll be reading the code of people who did, so this is only half-valuable). There is new c++11 code being written every day -- in volume (a hard to pin down amount) it's sadly more than 50%. The usage surveys don't really capture this clearly (and it's not clear they could).
Second: often new features are for library writers, or are out there for library writers to use (e.g. coroutines, which probably will not be appropriate for many users before c++23, but pretty much need to be available for people to experiment with).
Third: the new features tend to be additive. For example you don't need to use many of the stuff in -- stick to a for loop unless you want to take advantage of some new capability (e.g. policies, which are't ubiquitous). Concepts are the same way: they will improve error messages and reduce bugs, but if you don't use them your code will in 99.9% work just fine. When you see a very simple example that uses concepts, it's not surprising that the concepts don't really improve a simple add function -- the case is deliberately simple for explanatory purposes.
Languages move forward. Even go recently caved and added in generics.
Re: C++20 Concepts: The Definitive Guide
#38Earlier quoted context omitted.
How can floats be totally ordered. This isn’t even a matter of NaNs or not. A set of floats where two or more floats compare equal does not permit a total ordering.
What do you mean? I'm pretty sure no two distinct floats compare as equal.
Re: C++20 Concepts: The Definitive Guide
#39Earlier quoted context omitted.
How can floats be totally ordered. This isn’t even a matter of NaNs or not. A set of floats where two or more floats compare equal does not permit a total ordering.
What do you mean? I'm pretty sure no two distinct floats compare as equal.
Re: C++20 Concepts: The Definitive Guide
#40The right place to put a concept name, in production code, is in place of "typename" in a template definition, or even better in place of "T" in the function argument declaration. That is, instead of
template
T add(T a, T b)
requires addable (
return a + b;
)
say template
T add(T a, T b) {
return a + b;
}
or auto add(
addable auto a,
addable auto b) {
return a + b;
}
according as whether you want to enforce a and b to have the same type (which is another omission).Most often it is not necessary, and not wanted, to enforce a and b having the same type.