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

时间:2013-06-13 10:23:20

标签: c++ function namespaces scope 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();
}

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

1 个答案:

答案 0 :(得分:9)

<强> DRTL

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

<强>解释

电话

 std::cout << Foo::Baz();

实际上是

的中缀简写
 operator<<(std::cout, Foo::Baz());

因为函数调用是 unqualified (即没有任何名称空间前缀或周围的括号),编译器不仅会执行普通名称查找(从本地函数范围向外) ),以及参数依赖查找(又名 ADL ),用于两个参数operator<<的所有关联命名空间中的函数std::cout的其他重载班Baz。在这种情况下,这些关联的命名空间为stdFoo

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

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

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