【问题标题】:enable_if and mutually exclusive methodsenable_if 和互斥方法
【发布时间】:2014-12-08 14:06:17
【问题描述】:

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

【问题讨论】:

  • 定义“它不工作”。发生什么了?它与你想要发生的有什么不同?我们不能仅仅从一段代码中神奇地推断出您的意图,您自己承认,该代码不代表该目标
  • 已添加...但与“似乎实现这两种方法...”是多余的
  • 根本不是“冗余”,不。我们是科学家。我们重视precisionspecificsdata。 “似乎实现了这两种方法”都不是这些东西!

标签: c++ metaprogramming enable-if


【解决方案1】:

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

§14.8.2 [temp.deduct]/p8:

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

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

您可以根据类型部分特化整个类,或者通过向成员函数模板本身添加模板参数来自己引入直接上下文,这样替换失败可能会导致软错误:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-17
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 2020-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多