显式模板化转换运算符上的enable_if给出“invalid static_cast”

时间:2014-12-12 02:47:09

标签: c++ casting operator-overloading sfinae enable-if

我正在尝试做一个模板化的显式转换运算符。我发现,在符号上,你实际上可以在运算符的“名称”插槽中放置一个带有类型特征和std::enable_if的表达式。但是以下测试没有给出期望的行为:

#include <iostream>
#include <type_traits>

class WillCast {
public:
    explicit operator int () {
       return 1020;
    }
};

class WontCast {
public:
    template <typename T>
    typename std::enable_if<
        std::is_same<T, int>::value, int
    >::type toInteger()
    {
       return 1324;
    }

    template <typename T>
    explicit operator typename std::enable_if<
        std::is_same<T, int>::value, int
    >::type ()
    {
       return 304;
    }
};

int main() {
    std::cout << static_cast<int>(WillCast{}) << "\n";   // ok
    std::cout << WontCast{}.toInteger<int>() << "\n";    // ok
    /* std::cout << static_cast<int>(WontCast{}); */     // error 
};

从gcc 4.8.2返回的错误是:

test.cpp: In function ‘int main()’:
test.cpp:27:45: error: invalid static_cast from type ‘WontCast’ to type ‘int’
    std::cout << static_cast<int>(WontCast{});

如果我不想做的事情,我不会感到惊讶。但它似乎认为语法是正确的,它似乎并不像WontCast::toInteger()WillCast::operator int()看到的“附近”行为之间的行为一致。

(这是一个简化的例子,当然我想要的enable_if比较棘手。)


更新 - “补充工具栏情报(tm)”已经抛出How can I use std::enable_if in a conversion operator?,我没有通过“BeforeYouAsked intelligence(tm)”找到它。我会看看它是否有帮助。好吧,那里使用的解决方案似乎并不适用,因为WontCast不是模板类。所以没有帮助。

1 个答案:

答案 0 :(得分:4)

如果您将enable_if部分移动到模板中,则可以:

template <typename T,
          typename = typename std::enable_if<std::is_same<T, int>::value>::type
          >
explicit operator T()
{
    return 304;
}

鉴于:

int i = static_cast<int>(WontCast{}); // ok
double d = static_cast<double>(WontCast{}); // invalid static_cast