Reputation: 4500
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:
operator<<
overload for T = int
, the code compiles fine as well.What am I missing?
Upvotes: 1
Views: 281
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