Question

I've just made a template to detect if a data member of a class is static defined or not. The accessibility of the member isn't what it should be concerned about(Assuming the member is always accessible by the template) in this post. Here is the code with any symbols for testing:

#include <conio.h>
//#include <stdio.h>
#include <iostream>

struct A1
{
    int a;
};

struct A2
{
    static int a;
};

int A2::a{};

template < class My_Type >
struct TestStatic
{
    template < typename raw_ty > static char fTest(...);

    template < typename class_ty, typename arg_ty = decltype(class_ty::a) >
    static int fTest(int, arg_ty & = class_ty::a);

    enum nRes { result = sizeof(fTest<My_Type>(0)) - 1 };
};

int main(void)
{
    int i;

    i = TestStatic<A1>::result;
    std::cout << i << std::endl;
    i = TestStatic<A2>::result;
    std::cout << i << std::endl;
    _getch();
    return(0);
}

The question is when it was built with g++ 4.8 the compiling passed but got the result as two '3's rather than one '0' and another '3'. Is there anything wrong?

Was it helpful?

Solution

Your approach is fundamentally flawed, because decltype(T::x) is perfectly valid for non-static members:

#include <iostream>

struct T
{
    int x;
};

int main()
{
    std::cout << sizeof(decltype(T::x)) << '\n';
}

// Output: 4

You can get what you want with std::is_member_pointer:

If T is pointer to non-static member object or a pointer to non-static member function, provides the member constant value equal true. For any other type, value is false.

#include <iostream>
#include <type_traits>

struct T
{
    int x;
};

struct S
{
    static int x;
};

int main()
{
    std::cout << !std::is_member_pointer<decltype(&T::x)>::value << ' ';
    std::cout << !std::is_member_pointer<decltype(&S::x)>::value << '\n';
}

// Output: 0 1

This works because access to members through the :: syntax results in a pointer-to-member only if the member is not-static; it is of course a normal variable access when the member is static.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top