在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;
}
答案 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。