Earlier quoted context omitted.
> So what you’re saying is that it takes time, but works out? Probably depends on what you mean by "works out". I don't think GP would agree that delivering a less capable alternative qualifies. For example, one major feature C++0x concepts was supposed to have but got removed was definition-time checking - i.e., checking that your template only used capabilities promised by the concepts it uses, so if you defined a…
C++0x was ~5 years ago. C++26 concepts has more or less everything you mention, and you can try it out with all the major compilers right now.
You're quite a bit off. Tialaramex covered this well enough.
> C++26 concepts has more or less everything you mention, and you can try it out with all the major compilers right now.
Uh, no. No, it doesn't. Here's an example I wrote up earlier that demonstrates how concepts (still) don't have definition-time checking:
#include
template
concept fooable = requires(T t) {
{ t.foo() } -> std::same_as;
};
struct only_foo {
int foo();
};
struct foo_and_bar {
int foo();
int bar();
};
template
int do_foo_bar(T t) {
t.bar(); // No definition-time error despite fooable not specifying the presence of bar()
return t.foo();
}
// Succeeds despite fooable only requiring foo()
template int do_foo_bar(foo_and_bar t);
// Fails even though only_foo satisfies fooable
// template int do_foo_bar(only_foo t);
Here's Clang 21.1.0 compiling this in C++26 mode: https://cpp.godbolt.org/z/znPGvcTqs . Note that as-is the snippet compiles fine, but if you uncomment the last line you get an error despite only_foo satisfying fooable.Contrast this with Rust:
trait Fooable { fn foo(self) -> i32; }
fn do_foo_bar(t: T) -> i32 { let _ = t.bar(); // error[E0599]: no method named `bar` found for type parameter `T` in the current scope t.foo() }
Notice how do_foo_bar didn't need to be instantiated for the compiler to catch the error. That's what C++ concepts are unable to do, and as far as I know there is nothing on the horizon to change that.