Why does endl(std::cout) compile

后端 未结 2 1092
执念已碎
执念已碎 2021-02-02 00:44

Surprisingly the below code compiles and runs without error on a variety of compilers and versions.

#include 

int main() {
    endl(std::cout);
         


        
2条回答
  •  Happy的楠姐
    2021-02-02 01:06

    This behavior is called argument dependent lookup or Koenig lookup. This algorithm tells the compiler to not just look at local scope, but also the namespaces that contain the argument's type while looking for unqualified function call.

    For ex:

    namespace foo {
      struct bar{
        int a;
      };
    
      void baz(struct bar) {
        ...
      }
    };
    
    int main() {
      foo::bar b = {42};
      baz(b);  // Also look in foo namespace (foo::baz)
      // because type of argument(b) is in namespace foo
    }
    

    About the piece of code referred in question text:

    endl or std::endl is declared in std namespace as following:

    template< class CharT, class Traits >
    std::basic_ostream&     endl( std::basic_ostream& os );
    

    or

    std::ostream& endl (std::ostream& os);
    

    And cout or std::cout is declared as

    extern std::ostream cout;
    

    So calling std::endl(std::cout); is perfectly fine.

    Now when one calls just endl(std::cout);, because the type of argument cout is from std namespace, unqualified supposedly a function endl is searched in std namespace and it is found succesfully and confirmed to be a function and thus a call to qualified function std::endl is made.


    Further reading:

    1. GOTW 30: Name Lookup

    2. Why does 'std::endl' require the namespace qualification when used in the statement 'std::cout << std::endl;", given argument-dependent lookup?

提交回复
热议问题