The why is discussed in the answer by @DavisHerring. In this answer I want to share a pattern I was actually looking for when I encountered this question.
Depending on your use case, you maybe don't need the concept definition. If all you want to do is to avoid SFINAE trickery, you can directly invoke the requires clause and get rid of any concept at class scope:
struct A
{
template<typename T>
auto operator()(T t) const
{
if constexpr(requires { t.foo(); })
{
std::cout<<"foo"<<std::endl;
}
else
{
std::cout<<"no foo"<<std::endl;
}
}
};
and use that as
struct B { auto foo() {} };
struct C {};
int main()
{
A a;
a(B()); //prints "foo"
a(C()); //prints "no foo"
}
DEMO
However, if you find yourself using the same requires
statement multiple times in your class, the original question why you just can't declare it once at class scope is justified.
Thus, in order to work around code duplication, you can declare a single static function which contains the concept you are looking for, e.g.
struct A
{
template<typename T>
static constexpr auto concept_foo(T t)
{
return requires{ t.foo(); };
}
template<typename T>
auto operator()(T t) const
{
if constexpr(concept_foo(t))
{
std::cout<<"foo"<<std::endl;
}
else
{
std::cout<<"no foo"<<std::endl;
}
}
};
This pattern could replace most use cases for concepts at class scope.