Apparently, C++ concepts are only shallow.
#include <concepts>
template<class T>
T add(T a, T b)
{ return a + b;}
template<class T>
concept addable = requires(T a, T b)
{
{ add(a, b) } -> std::same_as<T>;
};
struct foo{};
static_assert(addable<int>);
static_assert(addable<foo>); // Passes?!
int main()
{
add(foo{}, foo{}); // Will not compile
}
Would it be possible somehow make evaluation of addable instantiate the template, so foo
no longer appears addable
? It is possible to introduce a constraint on the add
template, but I am looking for a more general approach:
- The compiler finds that the only match is a template
- The compiler tries to instantiate the template
- Instantiation fails somewhere down the expansion tree, and the concept evaluates to false