The code below fails to compile with gcc (9.2) and c++17. It does work with clang and MSVC, it also worked up to c++14. What's going on, who is right and is there an easy workaround? Resorted to #define
ing the unordered_set
overload away for gcc but I'd prefer a 'clean' solution.
#include <unordered_set>
#include <iostream>
struct Stream
{};
template <typename T, typename Alloc, template<typename, typename> class Container>
Stream & operator<< (Stream &stream, const Container<T, Alloc>& container)
{
std::cout << "container"<< std::endl;
return stream;
}
template <class K, class Hasher, class Keyeq, class Alloc>
Stream & operator<< (Stream &stream, const std::unordered_set<K, Hasher, Keyeq, Alloc> & container)
{
std::cout << "unordered_set"<< std::endl;
return stream;
}
int main()
{
Stream t;
std::unordered_set<int> set;
t << set;
return 0;
}
Result:
<source>: In function 'int main()':
<source>:25:7: error: ambiguous overload for 'operator<<' (operand types are 'Stream' and 'std::unordered_set<int>')
25 | t << set;
| ~ ^~ ~~~
| | |
| | std::unordered_set<int>
| Stream
<source>:8:10: note: candidate: 'Stream& operator<<(Stream&, const Container<T, Alloc>&) [with T = int; Alloc = std::hash<int>; Container = std::unordered_set]'
8 | Stream & operator<< (Stream &stream, const Container<T, Alloc>& container)
| ^~~~~~~~
<source>:15:10: note: candidate: 'Stream& operator<<(Stream&, const std::unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&) [with K = int; Hasher = std::hash<int>; Keyeq = std::equal_to<int>; Alloc = std::allocator<int>]'
15 | Stream & operator<< (Stream &stream, const std::unordered_set<K, Hasher, Keyeq, Alloc> & container)
| ^~~~~~~~
ASM generation compiler returned: 1
<source>: In function 'int main()':
<source>:25:7: error: ambiguous overload for 'operator<<' (operand types are 'Stream' and 'std::unordered_set<int>')
25 | t << set;
| ~ ^~ ~~~
| | |
| | std::unordered_set<int>
| Stream
<source>:8:10: note: candidate: 'Stream& operator<<(Stream&, const Container<T, Alloc>&) [with T = int; Alloc = std::hash<int>; Container = std::unordered_set]'
8 | Stream & operator<< (Stream &stream, const Container<T, Alloc>& container)
| ^~~~~~~~
<source>:15:10: note: candidate: 'Stream& operator<<(Stream&, const std::unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&) [with K = int; Hasher = std::hash<int>; Keyeq = std::equal_to<int>; Alloc = std::allocator<int>]'
15 | Stream & operator<< (Stream &stream, const std::unordered_set<K, Hasher, Keyeq, Alloc> & container)
| ^~~~~~~~
Execution build compiler returned: 1