简体   繁体   English

ADL 和 typedef

[英]ADL and typedefs

In short, I am trying to understand the behavior of Argument-Dependent Lookup in C++.简而言之,我试图了解 C++ 中参数相关查找的行为。 Some statements in ISO/IEC 14882:2017 (E) regarding ADL are not clear to me.我不清楚 ISO/IEC 14882:2017 (E) 中关于 ADL 的一些声明。 I hope somebody would clarify them to me.我希望有人向我澄清它们。

According to standard,按照标准,

Typedef names and using-declarations used to specify the types do not contribute to this set.用于指定类型的 Typedef 名称和 using 声明对这个集合没有贡献。

and

When considering an associated namespace, the lookup is the same as the lookup performed when the associated namespace is used as a qualifier (6.4.3.2) except that:考虑关联命名空间时,查找与将关联命名空间用作限定符 (6.4.3.2) 时执行的查找相同,除了:

  • Any using-directive s in the associated namespace are ignored...关联命名空间中的任何 using-directive 都将被忽略...

For me, these statements imply that ADL should completely ignore any typedef , or using occurrence.对我来说,这些陈述意味着 ADL 应该完全忽略任何typedefusing发生。 Probably, this is not the case.可能,情况并非如此。 Consider the following example:考虑以下示例:

#include <iostream>                                                             

using namespace std;                                                            

namespace N2                                                                 
{
    struct B {};

    template <typename T>                                                       
    void func (const T&) {cout << __PRETTY_FUNCTION__ << endl;}  
};

namespace N                                                                     
{
    typedef N2::B C;             
}                                                                               

void tfunc (N::C) {}                                                     

int main ()                                                     
{                                                                                                                      
    func(tfunc);                                                                 
}

It works, ie, the compiler is able to find func .它有效,即编译器能够找到func So, what those quotes from the standard actually mean?那么,标准中的那些引用实际上是什么意思?

This answer is provided by @IgorTandetnik.这个答案由@IgorTandetnik 提供。

What the standard is saying is that N2 is among the associated namespaces of tfunc , but N is not.标准所说的是N2tfunc的关联命名空间之一,但N不是。 In other words, void tfunc (N::C) works exactly the same as void tfunc(N2::B) .换句话说, void tfunc (N::C)工作原理与void tfunc(N2::B)完全相同。 If, in your example, you move func to N , it won't be found, despite the fact that, on the surface, the declaration of tfunc mentions N .如果在您的示例中,您将 func 移至N ,则不会找到它,尽管表面上tfunc的声明提到了N

Actually, if you just read a bit further down the standard, you can see why your code works.实际上,如果您只是进一步阅读标准,您就会明白为什么您的代码有效。 Specifically, N3337 [basic.lookup.argdep]/2 as shown below [emphasis mine]:具体来说,N3337 [basic.lookup.argdep]/2如下图【重点我的】:

The sets of namespaces and classes are determined in the following way:命名空间和类的集合按以下方式确定:

... ...

... ...

If T is a function type , its associated namespaces and classes are those associated with the function parameter types and those associated with the return type . 如果 T 是函数类型,则其关联的命名空间和类是与函数参数类型关联的命名空间和类以及与返回类型关联的命名空间和类。

As you can see, if the argument passed is a function type ( tfunc in your case), types associated with all the parameters ( N2::B is the only type), as well as the return type ( void - fundamental type, so not counted) are considered to create a set of associated namespaces.如您所见,如果传递的参数是函数类型(在您的情况下为tfunc )、与所有参数关联的类型( N2::B是唯一类型)以及返回类型( void - 基本类型,所以不计算在内)被认为是创建一组关联的命名空间。

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

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