This is similar to Understanding concepts. Check if a member is static, but that Q&A only asks why it doesn't work, and here I'm asking how to fix it.
Consider the following code:
struct A
{
static int x;
};
struct B
{
int x;
};
template <typename T>
concept C = requires
{
T::x;
};
static_assert(C<A>); // OK, as expected
static_assert(!C<B>); // Error, `C<B> == true` but I want it to be false
This code doesn't compile, because C<B> == true
, because T::x
is allowed even for nonstatic members in unevaluated contexts.
How do I make this compile? I.e., how can I make a concept that allows static
members, but rejects nonstatic members?
&& !requires(T t) {t.x;}
doesn't work, because it rejects static
members too, because t.x
is allowed for them.
&& !requires(T t) {&T::x;}
doesn't work also, because for static
members it forms a regular nonmember pointer.
[](auto){}(T::x);
but whereas it doesn't compile withB
, concept doesn't reject it :-/ Demotemplate <typename T> concept C = requires { [](auto*){}(&T::x); };
?auto*
will not match member pointers, see compiler-explorer.com/z/zEz49ezhc