Does Koenig search use here?

Is the following C ++ code code the following piece of code?

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

According to http://goo.gl/NkPNau, GCC compiles this remark, while Clang does not find operator<< (B).


In case you are wondering: this is the code that GTest uses with a custom operator<< for std::set to print messages with a good message. We could not figure out how to make it work with someone else besides placing operator<< (B) in the std namespace (yes, I know ...).

+5
source share
1 answer

Klang is true here. Let us call g ++ behavior a language extension.

An argument-dependent search (e.g. Koenig search) is used because m.str << t interpreted using the best overload matching either m.str.operator<<(t) or operator<<(m.str, t) , and the second case is unqualified-id as the name of the function. But:

14.6.4.2:

To call a function that depends on the template parameter, candidate functions are found using the usual search rules (3.4.1, 3.4.2, 3.4.3), except that:

  • For the search part that uses the unqualified name search (3.4.1) or the qualified name search (3.4.3), only function declarations from the template definition context are found.

  • For the search part using the associated namespaces (3.4.2), only function declarations found either in the context of the template definition or in the context of the template instance were found.

If the function name is an unqualified identifier, and the call is poorly formed or finds a better match, if the search in the corresponding namespaces were considered all declarations of functions with external connection introduced in these namespaces in all translation units, not just looking at those declarations that contain in the contexts of the template and the context of the template instance, the program has undefined behavior.

In the context of the definition of the template (B) is not displayed. (B) is displayed in the context of the template instance, but the global namespace is not an associated namespace either std::ostringstream or detail::Class .

+3
source

Source: https://habr.com/ru/post/1200267/


All Articles