I'm learning C++ concepts, and trying to realize why the following does not compile (it's just a trivial and meaningless example demonstrating the point; tested with GCC-11.1):
#include <iostream>
struct non_negatable {
};
template <class T>
auto negate(T a) {
return -a;
}
template <class T>
concept is_negatable = requires(T t) {
//just `-a;` would do the job of course
negate(t);
};
template <class T>
auto do_negate(T) {
std::cout << "here we are\n";
}
template <is_negatable T>
auto do_negate(T t) {
return negate(t);
}
int main() {
non_negatable x;
do_negate(x);
}
The above concept attempts to call a function template, whose implementation would not compile. This fact causes a "hard error", rather than failing the concept.
I guess it works this way because the concept requirements may be failed only by the expressions' "immediate context" ill-formness (like what we could observe with SFINAE).
Is my understanding correct? Where does the Standard describe this point? Is there a way to "fail" a concept based on a function template implementation ill-formness?