理解C++中的运算符范围

Kol*_*nya 5 c++ scope namespaces function argument-dependent-lookup

#include <iostream>

namespace Foo
{
    class Baz { };   

    std::ostream& operator<< ( std::ostream& ostream , const Baz& baz )
    {
        return ostream << "operator<<\n";
    }
}

int main()
{
    std::cout << Foo::Baz();
}
Run Code Online (Sandbox Code Playgroud)

operator<<Foo命名空间中定义了一个.为什么可以从全球范围调用它?

Tem*_*Rex 9

DRTL

编译器可以operator<<通过参数依赖查找找到用户定义的查找.

说明

电话

 std::cout << Foo::Baz();
Run Code Online (Sandbox Code Playgroud)

实际上是一个中缀速记

 operator<<(std::cout, Foo::Baz());
Run Code Online (Sandbox Code Playgroud)

因为函数调用是不合格的(即没有任何名称空间前缀或周围的括号),编译器不仅会执行普通的名称查找(从本地函数作用域向外),还会进行参数依赖查找(也称为ADL)以用于其他函数重载operator<<在参数和类的所有关联命名空间中.这些相关的命名空间,并在这种情况下.std::coutBazstdFoo

因此,依赖于参数的查找将找到定义

 std::operator<<(std::ostream&, /* all the builtin types and Standard strings and streams */)
 Foo::operator<<(std::ostream&, const& Baz)
Run Code Online (Sandbox Code Playgroud)

在名称查找之后,所有重载的参数推断都将失败std::operator<<.这就是重载解析会发现用户定义Foo::operator<<实际上是唯一匹配的原因.这就是它被召唤的原因.