enable_if和相互排斥的方法

enable_if and mutually exclusive methods

本文关键字:方法 if enable      更新时间:2023-10-16

我不明白为什么下面的代码不起作用。 编译器(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.
}

SFINAE 仅适用于即时上下文(SFINAE = SFIICINAE,即时上下文中的替换失败不是错误):

§14.8.2 [温度扣除]/p8:

只有函数类型及其模板参数类型的直接上下文中的无效类型和表达式才可能导致推导失败。

在成员函数的声明中替换类模板参数不是直接上下文,并且会导致失败时的错误。

您可以根据类型对整个类进行部分专用化,也可以通过将模板参数添加到成员函数模板本身来自己引入即时上下文,以便替换失败可能导致错误:

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; }