我刚刚制作了一个模板来检测类的数据成员是否是静态定义的。 成员的可访问性不是本文中应关注的(假定成员始终可通过模板访问)。 这是带有任何测试符号的代码:

#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);
}

问题是,当它是使用g ++ 4.8构建的时,编译通过了,但是结果是两个'3'而不是一个'0'和另一个'3'。 有什么问题吗?

===============>>#1 票数:4 已采纳

您的方法从根本上是有缺陷的,因为decltype(T::x) 对于非static成员完全有效

#include <iostream>

struct T
{
    int x;
};

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

// Output: 4

您可以使用std::is_member_pointer 获得所需的内容

如果T是指向非静态成员对象的指针或指向非静态成员函数的指针,则提供等于true的成员常量值。 对于任何其他类型,value为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

之所以有效,是因为只有在成员不是static ,才通过::语法访问成员会导致指向成员的指针。 当成员为static时,这当然是正常的变量访问。

  ask by unituniverse translate from so

未解决问题?本站智能推荐: