François Beaune
François Beaune

Reputation: 4500

Overloading operator<< for enum class inside template class

I can't seem to be able to overload operator<< for an enum class inside a template class:

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

The exact error message produced by Visual Studio 2015 is:

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

Both gcc and clang fail with a similar error message.

Two notes:

What am I missing?

Upvotes: 1

Views: 281

Answers (1)

Davis Herring
Davis Herring

Reputation: 39818

Your operator template cannot deduce T because of its use prior to :: (consider what specializing S might do to the type S::E). When using an unscoped enumeration, you’re getting one of the standard overloads via an implicit conversion to an integer.

The usual approach here is to define the operator as a (non-template) friend. Then overload resolution, rather than template argument deduction, is responsible for selecting among them.

Upvotes: 3

Related Questions