我正在尝试编写一个SFINAE模板,以确定是否可以将两个类添加在一起。这主要是为了更好地了解SFINAE的工作原理,而不是出于任何特定的“现实世界”原因。
所以我想出的是
#include <assert.h>
struct Vec
{
Vec operator+(Vec v );
};
template<typename T1, typename T2>
struct CanBeAdded
{
struct One { char _[1]; };
struct Two { char _[2]; };
template<typename W>
static W make();
template<int i>
struct force_int { typedef void* T; };
static One test_sfinae( typename force_int< sizeof( make<T1>() + make<T2>() ) >::T );
static Two test_sfinae( ... );
enum { value = sizeof( test_sfinae( NULL ) )==1 };
};
int main()
{
assert((CanBeAdded<int, int>::value));
assert((CanBeAdded<int, char*>::value));
assert((CanBeAdded<char*, int>::value));
assert((CanBeAdded<Vec, Vec>::value));
assert((CanBeAdded<char*, int*>::value));
}
这将编译除最后一行以外的所有内容,从而得到
finae_test.cpp: In instantiation of ‘CanBeAdded<char*, int*>’:
sfinae_test.cpp:76: instantiated from here
sfinae_test.cpp:40: error: invalid operands of types ‘char*’ and ‘int*’ to binary ‘operator+’
所以这个错误是我所期望的,但是我希望编译器然后找到test_sfinae(...)定义并使用它(而不是抱怨没有解析的错误)。
显然,我缺少了一些东西,只是不知道它是什么。
最佳答案
在我看来,您好像遇到了Core Issue 339和N2634中讨论的问题。最重要的是,即使标准允许您正在执行的操作,您也要超出任何编译器当前可以处理的范围。 C++ 0x将添加更多详细信息,说明什么将导致SFINAE失败以及将不会导致SFINAE失败和硬错误。如果您想了解血腥的细节,请参见N3000,第14.9.2节。