http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53012
Bug #: 53012 Summary: unrelated friend operators in same namespace interfere with operator resolution outside of namespace Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: kal...@gmail.com This code fails to compile because of "error: no match for ‘operator<<’ in ‘std::cout << val’": #include <iostream> namespace one { class A { }; } std::ostream& operator<<(std::ostream& os, const ::one::A& ) { return os << __PRETTY_FUNCTION__; } namespace two { class unrelated_a { friend std::ostream& operator<< ( std::ostream& out, const unrelated_a& ); }; class unrelated_b { friend std::ostream& operator<< ( std::ostream& out, const unrelated_b& ); }; void output( const one::A& val ) { std::cout << val << std::endl; } } int main() { one::A obj ; two::output( obj ); return 0; } Ways to make it compile as expected: A) remove either of the two (or both) unrelated class friend operators. B) Move two::output outside of the two namespace. C) use clang (not trying to be overly snarky here but being unsure myself if it should be valid code I compiled it using clang with success.) I've tried this on 4.6.3 and 4.7 with the same results. $ g++ -v Using built-in specs. COLLECT_GCC=./usr/bin/g++ COLLECT_LTO_WRAPPER=/mnt/gcc-4.7/usr/libexec/gcc/x86_64-unknown-linux-gnu/4.7.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: ../gcc-4.7.0/configure --prefix=/mnt/gcc-4.7/usr/ : (reconfigured) ../gcc-4.7.0/configure --prefix=/mnt/gcc-4.7/usr/ --disable-multilib --enable-languages=c++ Thread model: posix gcc version 4.7.0 (GCC) command to reproduce: ./usr/bin/g++ namespace_pain.cpp compiler output: namespace_pain.cpp: In function ‘void two::output(const one::A&)’: namespace_pain.cpp:28:16: error: no match for ‘operator<<’ in ‘std::cout << val’ namespace_pain.cpp:28:16: note: candidates are: <list of candidates> alternate command to reproduce: ./usr/bin/g++ namespace_pain.cpp --std=c++11 compiler output for alternate command: namespace_pain.cpp: In function ‘void two::output(const one::A&)’: namespace_pain.cpp:28:16: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’ In file included from /mnt/gcc-4.7/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/iostream:40:0, from namespace_pain.cpp:1: /mnt/gcc-4.7/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/ostream:600:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = one::A]’