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

#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

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

3回复

使用SFINAE检测模板化成员函数的存在

我了解到SFINAE可用于确定成员函数是否存在于类中。 例如,以下代码可用于检查方法hello是否存在于类中。 但是,假设hello是模板化的,我该如何修改技巧以使其仍能正常运行?
2回复

使用SFINAE检测constexpr

我正在努力升级一些C ++代码,以利用C ++ 11中的新功能。 我有一个trait类,其中有一些函数返回基本类型,这些类型通常在大多数情况下(但并非总是)返回常量表达式。 我想根据函数是否为constexpr做不同的事情。 我想出了以下方法: 这里有额外的int / ...参数,
1回复

SFINAE检测静态方法

我正在尝试实现一种机制来检测提供的类是否包含某些静态方法。 这是非常简单的代码,但我无法理解为什么decltype()不能像EnableIfHasFooMethod类的EnableIfHasFooMethod那样工作: 输出为0 ,但应为1 。
3回复

我可以使用SFINAE检测模板类成员函数吗?

我多次成功使用SFINAE。 检测类是否提供功能不是问题。 我当前的问题似乎与他的问题相反! 我宁愿只检测类的方法,而不是也检测派生的方法。 似乎与该方法是模板这一事实有关。 是否可以检测类模板方法? 我试图用不应该有害但没有运气的类型实例化模板。 错误信息: 请
1回复

SFINAE - 尝试确定模板类型是否具有带有'variable'返回类型的成员函数

遇到SFINAE问题。 我需要能够确定Type是否具有成员函数operator->,无论其返回类型如何。 示例如下。 这个类在测试者中。 它定义了operator - >(),返回类型为X *。 因此我不知道'X'到处硬编码是什么。 此类尝试确定传入的T是否具有
1回复

为类成员指针尝试时为什么SFINAE技巧不适用于非类类型?

出于好奇,我正在尝试使用sizeof()技巧替代实现is_class构造。 以下是代码: 问题是当我实例化is_class<int> ,它给出了编译错误: 现在,我的问题是,如果int T::*不适用于int (或void*等),那么为什么替换不能进行yes che
3回复

如何检测具有特定签名的静态成员函数的存在?

我在SO上发现了几个问题和答案,涉及在编译时(通过SFINAE)检测给定类是否具有某个名称,类型或签名的成员。 但是,我找不到一个也适用于静态公共成员函数(当指针到成员的技巧不起作用时)。 有任何想法吗?
1回复

尝试使用SFINAE(std :: enable_if)和模板特化时出现编译错误

考虑一下代码: Microsoft Visual Studio 2013给出以下错误: C2912:显式专门化'CByteArray serialize(const HLVariant&)'不是功能模板的专门化 错误C2783:'CByteArray serialize
2回复

使用SFINAE禁用模板类成员函数

假设我有一个接受某种类型T 。 这意味着它可以接受某些类型的optional<U> 。 如果它不是optional类型,我想禁用该功能,但是如果它是...,那么我想知道该类型U 我已经能够通过模板禁用该功能,但是我不知道如何在不两次编写同一个类并将一个模板模板版本化的情况下
1回复

使用SFINAE有条件地解析分配器成员

我正在为列表数据结构编写构造函数。 该类采用Allocator模板参数,如果未提供,则默认为std::allocator 。 由于C ++ 11分配器可能具有状态,因此默认构造函数也采用分配器对象。 当提供包含'member_'的自定义分配器时,以下行执行而不会失败。 但