模板类中的枚举类重载operator <<

时间:2019-12-22 16:05:42

标签: c++ c++11

对于模板类内部的枚举类,我似乎无法重载operator<<

#include <iostream>

template <typename T>
struct S
{
    enum class E { A, B };

    E e;
};

template <typename T>
std::ostream& operator<<(std::ostream& s, const typename S<T>::E e)
{
    return s << static_cast<int>(e);
}

int main()
{
    const S<int> s {};
    std::cerr << s.e;    // error
}

Visual Studio 2015产生的确切错误消息是:

error C2679: binary '<<': no operator found which takes a right-hand operand of type 'const S<int>::E' (or there is no acceptable conversion)

gcc和clang都失败,并显示类似的错误消息。

两个注意事项:

  • 如果我将枚举类更改为普通枚举,则代码可以正常编译。
  • 如果我将operator<<的{​​{1}}重载专门化,代码也可以正常编译。

我想念什么?

1 个答案:

答案 0 :(得分:3)

您的运算符模板无法推断出T,因为它是在::之前使用的(请考虑对S类型进行专门的S::E处理)。使用无范围的枚举时,您将通过隐式转换为整数来获得标准重载之一。

这里常用的方法是将运算符定义为(非模板)朋友。然后,重载解析(而不是模板参数推导)负责在它们之间进行选择。