WebFreak001
WebFreak001

Reputation: 2543

Check if class member is static

I have code like this and I want to check in my template (using a static if), if C.foo and C.bar are static or not:

class C {
    int foo;
    static int bar;
}

I tried these traits already but they don't seem to change for static members:

pragma(msg, __traits(hasMember, C, "foo")); // -> true
pragma(msg, __traits(hasMember, C.init, "foo")); // -> true
pragma(msg, __traits(hasMember, C, "bar")); // -> true
pragma(msg, __traits(hasMember, C.init, "bar")); // -> true

This hack which actually works for structs doesn't work for classes either:

pragma(msg, __traits(compiles, { enum tmp = __traits(getMember, C, "foo"); })); // -> false
pragma(msg, __traits(compiles, { enum tmp = __traits(getMember, C.init, "foo"); })); // -> false
pragma(msg, __traits(compiles, { enum tmp = __traits(getMember, C, "bar"); })); // -> false
pragma(msg, __traits(compiles, { enum tmp = __traits(getMember, C.init, "bar"); })); // -> false

Upvotes: 3

Views: 87

Answers (1)

Jonathan M Davis
Jonathan M Davis

Reputation: 38287

The trick is that static member variables do not have an offsetof property. So, you can do something like

template isStaticMember(T, string memberName)
    if(__traits(hasMember, T, memberName))
{
    mixin("alias member = " ~ T.stringof ~ "." ~ memberName ~ ";");
    enum isStaticMember = !__traits(compiles, member.offsetof);
}

class C
{
    int foo;
    static int bar;
}

void main()
{
    static assert(!isStaticMember!(C, "foo"));
    static assert(isStaticMember!(C, "bar"));
}

There probably should be something in std.traits for this, but there isn't yet.

Upvotes: 4

Related Questions