|
|
|
|
|
by aw1621107
339 days ago
|
|
Concepts are basically a half solution - they check that a type has some set of properties, but they don't check that the implementation only uses those properties. As a result, even with concepts you can't know what types will work in a template without looking at the implementation as well. Example [0]: #include <concepts>
template<typename T>
concept fooable = requires(T t) {
{ t.foo() } -> std::same_as<int>;
};
struct only_foo {
int foo();
};
struct foo_and_bar {
int foo();
int bar();
};
template<fooable T>
int do_foo_bar(T t) {
t.bar(); // Compiles 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>(foo_and_bar t);
// Fails even though only_foo satisfies fooable
template int do_foo_bar<only_foo>(only_foo t);
[0]: https://cpp.godbolt.org/z/jh6vMnajj |
|
I'd say that's a mistake of the person who wrote the template then.
Also, there are Concepts where you absolutely know which types are allowed, e.g. std::same_as, std::integral, std::floating_point, etc.