ADL是否可用于全局名称空间? [英] Does ADL work for the global namespace?

查看:109
本文介绍了ADL是否可用于全局名称空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

示例 ADL 用于注入"特定的函数/运算符,具体取决于fn/op所适用的类型.

我想知道ADL是否完全适用于全局名称空间,即是否在委员会名望的丹尼尔·克鲁格勒(DanielKrügler)描述这样的ADL问题:

此不合格的调用具有不合格名称查找的效果 发生,因此,编译器将搜索 名称operator<<.从词法位置开始 发现operator<<调用是向上" (...),它从当前名称空间开始,并且所有 包含该名称空间的名称空间(包括全局名称空间 命名空间,顺便说一下)和-...

Emph.矿.请注意,如何将外部名称空间描述为仅从词法位置"... ..."开始.他继续:

...,并且-作为第二条路线-它执行了此操作的第二阶段 在编译器的所谓关联名称空间中进行查找 此调用中出现的参数类型.

在给出的示例中,搜索的第一阶段失败,因为 在#include <iterator>存在的位置,没有 任何名称空间中这些参数类型的对应operator<<. 请注意,您在之后以词法提供了operator<<的声明 operator<<的调用发生在某些 库头. 搜索的第二阶段还将 考虑哪些地点 跟随实际的函数调用,但仅在关联的名称空间中.

大胆的雌雄同体.矿.因此在我看来, 与ADL适用于全局名称空间有关.当然,我很容易误会了一些东西.


注意:这可能是标准的一种情况,只是没有明确地一种或另一种方式提及它,因为全局NS就像任何其他名称空间一样-再次,我所知该标准的内容非常有限.

解决方案

完全忘记了我最初的答案,这是完全错误的.

根据C ++ 11标准,关于ADL(重点是我)的§3.4.2:

当函数调用(5.2.2)中的postfix-expression是 非限定ID,通常不考虑使用其他名称空间 可以搜索不合格的查找(3.4.1),在这些命名空间中, 名称空间范围的朋友函数声明(11.3)否则 可见.

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

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.

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?

Specifically, are these equivalent wrt. 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. global namespace scope not needing ADL: (update after a now deleted answer)

One Daniel Krügler of Committee fame describes an ADL problem as such:

This unqualified call has the effect that unqualified name lookup happens and as a consequence of this, the compiler searches for the name 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 - ...

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. 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. 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. 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.

解决方案

Completely forget my initial answer, it was plain wrong.

From the C++11 standard, §3.4.2 on ADL (emphasis mine):

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.

So in short, since unqualified lookup will always search in the global namespace, ADL will never apply to global namespace.

这篇关于ADL是否可用于全局名称空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆