简体   繁体   English

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

[英]Does ADL work for the global namespace?

Examples such as enabling outputting of std types explain how ADL can be used to "inject" a certain function/operator, depending on the type the fn/op is applied to. 诸如启用std类型输出的示例解释了如何使用ADL “注入”某个函数/运算符,具体取决于应用fn / op的类型。

I was wondering wheter ADL fully applies to the global namespace, that is, whether a type declared (or made available via using ) at global namespace scope makes ADL look for matching functions in the global namespace? 我想知道ADL是否完全适用于全局命名空间,也就是说,在全局命名空间范围内声明(或通过using可用)的类型是否使ADL在全局命名空间中查找匹配函数?

Specifically, are these equivalent wrt. 具体来说,这些是等价的。 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. WRT。 global namespace scope not needing ADL: (update after a now deleted answer) 全局命名空间范围不需要ADL :(在现在删除的答案后更新)

One Daniel Krügler of Committee fame describes an ADL problem as such: 委员会成名的DanielKrügler描述了一个ADL问题

This unqualified call has the effect that unqualified name lookup happens and as a consequence of this, the compiler searches for the name operator<< . 这种不合格的调用会产生无限制的名称查找,因此编译器会搜索名称operator<< beginning from the lexical location where the operator<< call is found "upwards" (...) starting in the current namespace and all the namespaces that include that namespace (including the global namespace, btw.) and - ... 当前名称空间中开始operator<< call is uply“ (...) 的词汇位置开始,以及包含该名称空间的所有名称空间(包括全局名称空间,btw。)和 - ...

Emph. EMPH。 mine. 矿。 Note how the outer namespaces are described to only be considered "... from the lexical location ...". 请注意外部名称空间的描述如何仅被视为“...... 来自词汇位置 ......”。 He continues: 他继续:

... and - as a second route - it performs a second phase of this lookup the compiler searches in the so-called associated namespaces of the argument types occurring in this call. ...和 ​​- 作为第二个路径 - 它执行此查找的第二阶段,编译器在此调用中发生的参数类型的所谓关联命名空间中搜索。

In the presented example, the first phase of the search fails, because at the point where #include <iterator> exists, there is no corresponding operator<< for these argument types in any namespace. 在给出的示例中,搜索的第一阶段失败,因为在#include <iterator>存在的点上,任何名称空间中的这些参数类型都没有对应的operator<< Note that your declaration of operator<< is provided lexically after the point where the call of operator<< happens somewhere in some of the library headers. 请注意,您的声明operator<<是哪里的电话点词法提供operator<<在一些库头的地方发生。 The second phase of the search would also consider locations that follow the actual function call , but only within the associated namespaces. 搜索的第二阶段也将考虑按照实际函数调用的位置 ,但只有在相关的命名空间。

Bold emph. 大胆的恩赐。 mine. 矿。 So it would seem to me it is relevant that ADL works for the global namespace. 因此,在我看来,ADL适用于全局命名空间相关的。 Of course I could easily have misunderstood something. 当然,我很容易误解一些事情。


Note: This may be a case of the standard simply not explicitly mentioning it one way or another, because the global NS is just like any other namespace -- then again it may not, my knowledge of the Standard is very limited. 注意:这可能是标准的一种情况,只是没有明确地以某种方式提及它,因为全局NS就像任何其他命名空间一样 - 然后它可能不会,我对标准的了解非常有限。

Completely forget my initial answer, it was plain wrong. 完全忘记我最初的答案,这是完全错误的。

From the C++11 standard, §3.4.2 on ADL (emphasis mine): 从C ++ 11标准,关于ADL的§3.4.2(强调我的):

When the postfix-expression in a function call (5.2.2) is an unqualified-id, other namespaces not considered during the usual unqualified lookup (3.4.1) may be searched, and in those namespaces, namespace-scope friend function declarations (11.3) not otherwise visible may be found. 当函数调用(5.2.2)中的postfix-expression是非限定id时,可以搜索在通常的非限定查找 (3.4.1) 期间未考虑的其他名称空间,并在这些名称空间中搜索名称空间范围的朋友函数声明( 11.3)可能没有其他可见的。

So in short, since unqualified lookup will always search in the global namespace, ADL will never apply to global namespace . 简而言之,由于非限定查找将始终在全局命名空间中进行搜索,因此ADL将永远不会应用于全局命名空间

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM