ADL是否适用于全局命名空间?

时间:2014-08-05 07:31:19

标签: c++ namespaces using argument-dependent-lookup global-namespace

Examples such as支持输出std类型,解释ADL如何用于注入"注入"某个函数/运算符,具体取决于fn / op的类型。

我想知道ADL完全适用于全局命名空间,也就是说,在global namespace scope声明(或通过using提供)的类型是否使ADL在全局命名空间中查找匹配函数?

具体来说,这些是等价的。 ADL:

// 1 - at global namespace scope
struct GlobalType {};

template< class Ch, class Tr>
std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& os, GlobalType const& x)
{
    os << ...;
    return os;
} 

// 2 - within namespace
namespace ecaps {

    struct EcapsType {};

    template< class Ch, class Tr>
    std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& os, EcapsType const& x)
    {
        os << ...;
        return os;
    } 

}

// 3 - Type brought to global NS via using, function at global scope
namespace other {
    struct OtherType {};    
}

using other::OtherType;

template< class Ch, class Tr>
std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& os, OtherType const& x)
{
    os << ...;
    return os;
} 

WRT。全局命名空间范围不需要ADL :(在现在删除的答案之后更新)

一个Daniel Krügler of Committee fame describes an ADL problem

  

此不合格的调用具有非限定名称查找的效果   发生,因此,编译器搜索   名称operator<<。从词汇位置开始   operator<<调用已找到&#34;向上&#34; (...)从当前命名空间开始,所有   包含该命名空间的命名空间(包括全局   命名空间,顺便说一句。)和 - ...

EMPH。矿。请注意外部名称空间如何被描述为仅从词汇位置 ...&#34;&#34; ... 。他继续说道:

  

......和 ​​- 作为第二条路线 - 它执行第二阶段   在所谓的关联命名空间中查找编译器搜索   此调用中发生的参数类型。

     

在提供的示例中,搜索的第一阶段失败,因为   在#include <iterator>存在的地方,没有   任何命名空间中的这些参数类型对应operator<<。   请注意,{/ 1}}的声明是在之后以词法提供的   operator<<的调用在某些地方发生的地方   库头。 搜索的第二阶段也将   考虑那些地点   跟随实际的函数调用,但仅限于关联的命名空间内。

Bold emph。矿。因此,在我看来,相关,ADL适用于全局命名空间。当然,我很容易误解了一些事情。


注意:这个可能是标准的一个例子而不是以某种方式明确地提及它,因为全局NS就像任何其他命名空间一样 - 然后它可能不是,我的知识该标准非常有限。

1 个答案:

答案 0 :(得分:2)

完全忘记我的初步答案,这是完全错误的。

从C ++ 11标准,关于ADL的§3.4.2(强调我的):

  

当函数调用(5.2.2)中的postfix-expression是一个   unqualified-id,其他名称空间在通常情况下不予考虑   可以搜索非限定查找(3.4.1),并在这些名称空间中,   命名空间范围的友元函数声明(11.3),否则没有   可以找到可见的。

简而言之,由于不合格的查找将始终在全局命名空间中搜索, ADL将从不应用于全局命名空间