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.
T::x is a pointer-to-member in the case of non-static members, so it matches both static and non-static members.
You can exclude the pointer-to-member by using
#include <type_traits>
template <typename T>
concept C = requires {
{ T::x };
} && !std::is_member_pointer_v<decltype(&T::x)>;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With