gpt4 book ai didi

c++ - 无法理解 int 和用户定义类型之间的名称查找差异 - 可能与 ADL 相关

转载 作者:可可西里 更新时间:2023-11-01 16:37:59 25 4
gpt4 key购买 nike

为什么下面的代码可以编译:

template<typename T>
void foo(T in) { bar(in); }

struct type{};
void bar(type) {}
int main() { foo(type()); }

当以下情况不存在时:

template<typename T>
void foo(T in) { bar(in); }

void bar(int) {}
int main() { foo(42); }

使用 GnuC++ 7 编译:

a.cpp: In instantiation of 'void foo(T) [with T = int]':
a.cpp:9:20: required from here
a.cpp:2:21: error: 'bar' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
void foo(T in) { bar(in); }
~~~^~~~
a.cpp:8:6: note: 'void bar(int)' declared here, later in the translation unit void bar(int) {}

我假设 MSVC 会编译两者(就像它所做的那样),但 GCC 会拒绝这两者,因为 GCC/Clang 具有适当的两阶段名称查找...

最佳答案

奇怪的部分不是 int 示例编译失败,而是 type 示例编译失败,因为 bar 是在 。这是由于 [temp.dep.candidate](见第三段)。

模板的二次编译

当编译器解析和编译模板类或函数时,它分两次查找标识符:

  • 模板参数独立名称查找:可以检查不依赖于模板参数的所有内容。在这里,由于 bar() 依赖于模板参数,因此什么都不做。此查找在定义点完成。
  • 依赖于模板参数的名称查找:现在可以在 pass #1 中查找所有无法查找的内容。此查找在实例化时完成。

您在第 2 遍中遇到错误。


ADL 查找

查找函数名称时,它是在当前上下文和参数类型的上下文中完成的。例如,尽管 f 是在命名空间 n 中定义的,但以下代码是有效的:

namespace n { struct type {}; void f(type) {}; }
int main() { n::type t; f(t); } // f is found in ::n because type of t is in ::n

More about ADL (cppreference.com) :

Argument-dependent lookup, also known as ADL, or Koenig lookup, is the set of rules for looking up the unqualified function names in function-call expressions, including implicit function calls to overloaded operators. These function names are looked up in the namespaces of their arguments in addition to the scopes and namespaces considered by the usual unqualified name lookup.


两次编译、ADL 查找和非限定 ID 查找

在您的情况下,这三种机制会发生冲突。见 [temp.dep.candidate]:

For a function call that depends on a template parameter, if the function name is an unqualified-id but not a template-id, the candidate functions are found using the usual lookup rules (3.4.1, 3.4.2) except that:
— For the part of the lookup using unqualified name lookup (3.4.1), only function declarations with external linkage from the template definition context are found.
— For the part of the lookup using associated namespaces (3.4.2), only function declarations with external linkage found in either the template definition context or the template instantiation context are found.

因此,使用 foo(type()) unqualified-id 查找开始,查找完成“在模板定义上下文或模板实例化中”
对于 foo(42)42 是基本类型,不考虑 ADL,只考虑“定义上下文”

关于c++ - 无法理解 int 和用户定义类型之间的名称查找差异 - 可能与 ADL 相关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46242144/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com