Koenig';你在这里申请什么? 下面的代码段正确的C++代码?< /P> #include <sstream> class Foo; std::ostream& operator<<(std::ostream& str, Foo x); // (A) namespace test { class Message { public: std::ostringstream str; }; template<typename T> Message& operator<<(Message& m, T& t) { using ::operator<<; m.str << t; return m; } } namespace detail { class Class { public: int i; Class() : i(5) {} }; } std::ostream& operator<<(std::ostream& str, detail::Class& myClass) { // (B) return str << myClass.i; } int main() { test::Message m; detail::Class c; m << c; } #包括 Foo类; std::ostream&operator

Koenig';你在这里申请什么? 下面的代码段正确的C++代码?< /P> #include <sstream> class Foo; std::ostream& operator<<(std::ostream& str, Foo x); // (A) namespace test { class Message { public: std::ostringstream str; }; template<typename T> Message& operator<<(Message& m, T& t) { using ::operator<<; m.str << t; return m; } } namespace detail { class Class { public: int i; Class() : i(5) {} }; } std::ostream& operator<<(std::ostream& str, detail::Class& myClass) { // (B) return str << myClass.i; } int main() { test::Message m; detail::Class c; m << c; } #包括 Foo类; std::ostream&operator,c++,C++,Clang在这里是正确的。让我们把g++的行为称为语言扩展 依赖于参数的查找(也称为Koenig查找)确实适用,因为m.str供将来参考,当编译器给你一个错误时,发布确切的错误(即使你正确地总结了它)。如果它是有效的,我不知道它是如何因为ADL(Koenig查找):表达式没有全局命名空间为关联命名空间的任何类型。我很惊讶GCC和Intel接受了这一点,但我不能说他们这样做是错误的,而不理解他们为什么这么做。我相信Clang是正确的,代码是无效的。在两阶段查找下,operator要添加到我前面的注

Clang在这里是正确的。让我们把g++的行为称为语言扩展


依赖于参数的查找(也称为Koenig查找)确实适用,因为
m.str供将来参考,当编译器给你一个错误时,发布确切的错误(即使你正确地总结了它)。如果它是有效的,我不知道它是如何因为ADL(Koenig查找):表达式没有全局命名空间为关联命名空间的任何类型。我很惊讶GCC和Intel接受了这一点,但我不能说他们这样做是错误的,而不理解他们为什么这么做。我相信Clang是正确的,代码是无效的。在两阶段查找下,
operator要添加到我前面的注释中,GCC这样做是因为GCC已经完成了。如果之前还有任何关于哪个编译器是正确的问题,现在就不应该了。Fiktik:为什么要使用::operator实现
呢?什么是一个符合标准的好解决方案来完成OP想要做的事情呢?我会把(B)放在
名称空间细节中。如果出于某种原因希望它在全局命名空间中可见,请使用细节:
operator@aschepler但除非我误读了这个问题,否则OP的
operator@hvd:什么
operator@RSahu:良好的标准兼容解决方案是将ADL用于其设计内容和设计方式。运算符应位于两个参数之一的命名空间中。