Проблема шаблона Sfinae Canadd
Вопрос
Я пытаюсь выписать шаблон 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 (...) и вместо этого использует его (и не жалуется на то, что не разрабатывает.
Ясно, что я что -то упускаю, я просто не знаю, что это такое.
Решение
Мне кажется, что вы столкнулись с проблемой, которая обсуждается в Основной выпуск 339 так же как N2634. Анкет Суть в том, что вы немного выходите за рамки того, что любой компилятор может справиться в настоящее время, даже если то, что вы делаете, разрешено стандартом. C ++ 0x добавит более подробную информацию о том, что будет и не приведет к сбое Sfinae в сравнении с жесткой ошибкой. Видеть N3000, §14.9.2, если вы хотите попасть в кровавые детали.