Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a concept, how can I check that a member is static?

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.

like image 702
HolyBlackCat Avatar asked Nov 17 '25 02:11

HolyBlackCat


1 Answers

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)>;
like image 90
Raildex Avatar answered Nov 18 '25 17:11

Raildex



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!