我无法理解为什么以下代码无效。编译器(gcc)似乎同时发生了两种情况 方法和显然整数是有符号或无符号的,所以总是失败。我虽然在这里使用enable_if来避免这种情况。
问:为什么编译错误,如何避免呢?using namespace boost; // or std as you want
template<typename T>
struct test {
// if signed
template< typename enable_if
< is_signed<T>
, int
>:: type = 0
>
test &operator<<=(int value)
{}
// if unsigned
template< typename enable_if
< is_unsigned<T>
, int
>:: type = 0
>
test &operator<<=(int value)
{}
};
void foo()
{
test<int> x;
x << 1; // COMPILE ERROR no type named 'type' in struct enable_if<unsigned> etc.
test<unsigned> y;
y << 1; // COMPILE ERROR no type named 'type' in struct enable_if<int> etc.
}
答案 0 :(得分:5)
SFINAE仅适用于immediate context(SFINAE = SFIICINAE,直接上下文中的替换失败不是错误):
§14.8.2[temp.deduct] / p8:
只有函数类型的直接上下文中的无效类型和表达式及其模板参数类型才会导致演绎失败。
在成员函数声明中替换类模板参数不是直接上下文,并且在失败时会导致 hard 错误。
您可以根据类型部分特化整个类,或者通过向成员函数模板本身添加模板参数来自行引入直接上下文,以便替换失败可导致< em> soft 错误:
template <typename U = T, typename std::enable_if<std::is_signed<U>{}, int>::type = 0>
test &operator<<=(int value)
{ return *this; }
template <typename U = T, typename std::enable_if<std::is_unsigned<U>{}, int>::type = 0>
test &operator<<=(int value)
{ return *this; }