奇怪的建议模板参数转换

时间:2016-01-15 15:12:17

标签: c++ templates type-conversion pointer-to-member

在C ++模板书上 - 完整指南,Vandevoorde& Josuttis,建议使用以下片段来确定某个类型是否为类。参数是:“对于类类型,我们可以依赖观察指向成员类型构造int C :: *仅在C是类类型时才有效”作为决定类型是否为“类”类型的策略或不。

我有两个问题:

1)你认为这个论点有效吗? 2)你如何修改(保留策略)下面的代码段以使其工作,因为它不能在MSVC2013上编译?

using namespace std;

template<typename T>
class IsClass
{
    typedef char One;
    typedef struct 
    { 
        char a[2];
    } Two;
    template<typename C> static One test(int C::*);
    template<typename C> static Two test(...);
public:
    enum { YES = (sizeof(IsClass<T>::test<T>(0) == 1)) };
};

class C{};

void main()
{
    if (IsClass<C>::YES)
        std::cout << "C Is a Class" << endl;
}

1 个答案:

答案 0 :(得分:0)

与评论相反,您的问题与表达SFINAE无关。这是沼泽标准的原始配方SFINAE:您正在检查类型 int C::*的格式良好。

在我们开始之前,你把它括起来是错误的。您希望将sizeof应用于test的结果,而不是==

enum { YES = (sizeof(IsClass<T>::test<T>(0)) == 1) };
             //     ^                      ^

(另外,get rid of void main()。)

现在,MSVC 2013由于某种原因尝试进行演绎,如果您进行合格的呼叫,则会忽略指定的模板参数:

    IsClass<T>::test<T>(0)
//  ^^^^^^^^^^^^

这显然是一个错误。我不确定为什么它会这样表现,但是MSVC前端的大部分都是用胶带粘在一起的,所以我并不感到惊讶。

无论如何你都不需要合格的电话。只需写下test<T>(0)并进行无限制的通话:

enum { YES = (sizeof(test<T>(0)) == 1) };

适用于我的MSVC 2013。