Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 何时考虑对非限定从属名称进行ADL查找?_C++_C++17 - Fatal编程技术网

C++ 何时考虑对非限定从属名称进行ADL查找?

C++ 何时考虑对非限定从属名称进行ADL查找?,c++,c++17,C++,C++17,我在cpp参考资料中对此进行了讨论 我认为普通+ADL查找在这两种情况下都会生成以下集合:f(char)(普通查找), f(int)/f(E)(ADL查找,因为它考虑了POI的可见性)然后重载解析将在第一种情况下选择f(E),在另一种情况下选择f(int) 你能给我解释一下在这种情况下引擎盖下到底发生了什么(查找、过载解析) 非常感谢 示例: void f(char); // first declaration of f template<class T> void g(T t

我在cpp参考资料中对此进行了讨论

我认为普通+ADL查找在这两种情况下都会生成以下集合:f(char)(普通查找), f(int)/f(E)(ADL查找,因为它考虑了POI的可见性)然后重载解析将在第一种情况下选择f(E),在另一种情况下选择f(int)

你能给我解释一下在这种情况下引擎盖下到底发生了什么(查找、过载解析)

非常感谢

示例:

void f(char); // first declaration of f
 
template<class T> 
void g(T t) {
    f(1);    // non-dependent name: lookup finds ::f(char) and binds it now
    f(T(1)); // dependent name: lookup postponed
    f(t);    // dependent name: lookup postponed
//  dd++;    // non-dependent name: lookup finds no declaration
}
 
enum E { e };
void f(E);   // second declaration of f
void f(int); // third declaration of f
double dd;
 
void h() {
    g(e);  // instantiates g<E>, at which point
           // the second and the third uses of the name 'f'
           // are looked up and find ::f(char) (by lookup) and ::f(E) (by ADL)
           // then overload resolution chooses ::f(E).
           // This calls f(char), then f(E) twice
    g(32); // instantiates g<int>, at which point
           // the second and the third uses of the name 'f'
           // are looked up and find ::f(char) only
           // then overload resolution chooses ::f(char)
           // This calls f(char) three times
}
void f(char);//f.第一次声明
模板
空隙g(T){
f(1);//非依赖名称:查找找到::f(char)并立即绑定它
f(T(1));//依赖名称:查找延迟
f(t);//依赖名称:查找延迟
//dd++;//非依赖名称:查找未找到任何声明
}
枚举E{E};
无效f(E);//f.第二次声明
空f(int);//f.第三次声明
双dd;
void h(){
g(e);//实例化g,此时
//“f”的第二个和第三个用法
//查找并查找::f(char)(通过查找)和::f(E)(通过ADL)
//然后重载解析选择::f(E)。
//这将调用f(char),然后调用f(E)两次
g(32);//实例化g,此时
//“f”的第二个和第三个用法
//仅查找并查找::f(char)
//然后重载解析选择::f(char)
//这个函数调用f(char)三次
}

ADL在与参数类型相关联的命名空间(或类)中查找函数。因此,如果在命名空间
X
中声明
enum E
,ADL将只在命名空间
X
中查找(请参见下文)。基本类型如
int
没有任何关联的命名空间。所以基本类型的ADL永远找不到任何东西

void f(char); // first declaration of f
 
template<class T> 
void g(T t) {
    f(1);    // non-dependent name: lookup finds ::f(char) and binds it now
    f(T(1)); // dependent name: lookup postponed
    f(t);    // dependent name: lookup postponed
//  dd++;    // non-dependent name: lookup finds no declaration
}

namespace X {
    enum E { e };
    void f(E);   // second declaration of f
    void f(int); // third declaration of f
    }
double dd;

void f(int);//the global namespace is not associated to fundamental types
 
void h() {
    //The associated scope of X::e is namespace X.
    g(X::e);  // instantiates g<E>, at which point
           // the second and the third uses of the name 'f'
           // are looked up and find ::f(char) (by lookup) and X::f(int) and X::f(E) (by ADL)
           // then overload resolution chooses X::f(E).
           // This calls f(char), then X::f(E) twice

    //Fundamental types do not have any associated namespace
    g(32); // instantiates g<int>, at which point
           // the second and the third uses of the name 'f'
           // are looked up and find ::f(char) only
           // then overload resolution chooses ::f(char)
           // This calls f(char) three times
}
void f(char);//f.第一次声明
模板
空隙g(T){
f(1);//非依赖名称:查找找到::f(char)并立即绑定它
f(T(1));//依赖名称:查找延迟
f(t);//依赖名称:查找延迟
//dd++;//非依赖名称:查找未找到任何声明
}
名称空间X{
枚举E{E};
void f(E);//第二次声明f
void f(int);//f的第三个声明
}
双dd;
无效f(int)//全局命名空间与基本类型不关联
void h(){
//X::e的关联范围是命名空间X。
g(X::e);//实例化g,此时
//“f”的第二个和第三个用法
//查找并查找::f(char)(通过查找)和X::f(int)以及X::f(E)(通过ADL)
//然后重载解析选择X::f(E)。
//这将调用f(char),然后调用X::f(E)两次
//基本类型没有任何关联的命名空间
g(32);//实例化g,此时
//“f”的第二个和第三个用法
//仅查找并查找::f(char)
//然后重载解析选择::f(char)
//这个函数调用f(char)三次
}

@OlafDietsche-Nope,这个问题根本不涉及依赖模板的名称查找。我认为这里根本不涉及ADL。您没有
E
所属的命名空间或类。@super因此,当在模板定义上下文中进行普通查找时,它是如何找到f(E)(请参阅)的。文档声明“对于枚举类型的参数,定义枚举的命名空间将添加到集合中。如果枚举类型是类的成员,则该类将添加到集合中”。这是否意味着在这种情况下,ADL将全局名称空间视为包含名称空间的枚举?在这种情况下,它会考虑F(int)在过载分辨率之前?@ Nop666,我猜想它是与点的关系,而不是ADL。ADL只查找未通过常规查找搜索的名称空间。全局名称空间是通过常规查找进行搜索的。@nop666请参见示例。您是对的:如果T是基本的,关联的实体和名称空间在ADL中是空集lookup@nop666事实上,由于指针具有与指针对象类型相关联的名称空间,基本指针比内置指针更精确。我刚刚意识到,您的示例使用封闭名称空间以及基本指针类型解释了该行为。但是,如注释中所述,在原始示例中检测f(E)的情况如何?@nop666在原始示例中,封闭的名称空间是全局名称空间。这个没有灵感的原始示例当然是一个混乱的来源。好吧,因此你同意f(E)(我认为还有f(int))是通过对f(E)的ADL查找(在全局ns中查找CPPPreference示例)找到的,即使在没有灵感的情况下,f(E)也是通过过载解析来选择的