gpt4 book ai didi

c++ - ADL 名称查找问题,正在使用 std::swap; swap(a,b) 与函数重载或内部作用域函数隐藏外部作用域函数有关?

转载 作者:行者123 更新时间:2023-12-02 10:16:37 25 4
gpt4 key购买 nike

我知道 ADL 是什么,我知道在 C++ 中,内部作用域函数隐藏外部作用域函数。也就是说,名称不会跨范围重载。所以函数重载需要在相同的范围内完成。

现在我的问题是,对于这个通用代码片段:

#include <iostream>
#include <string>
using std::cout;
using std::endl;

namespace Foo{
class Bar{
friend void swap(Bar& a, Bar& b);
};
void swap(Bar& a, Bar& b){
cout << "I am here" << endl;
}
}

int main(int argc, char *args[]){
Foo::Bar a, b;
using std::swap; //These 2 lines
swap(a, b); //output is "I am here", Foo::swap is called
}

与 ADL 一起,是:

  1. 自定义 swapstd::swap 都可见并被认为是重载,然后选择最佳匹配?

  2. 首先找到自定义 swap,然后名称查找停止(std::swap 被隐藏)?


如果 1. 为真,它是如何工作的?函数重载超过 2 个不同的范围?这与我开头写的矛盾。 使用 std::swapstd::swap 引入当前作用域。自定义 swapFoo::swap 中。

顺便说一句,这个答案What is “Argument-Dependent Lookup” (aka ADL, or “Koenig Lookup”)?似乎表明它们是函数重载。

Further, if for some reason both A::swap(A::MyClass&, A::MyClass&) and std::swap(A::MyClass&, A::MyClass&) are defined, then the first example will call std::swap(A::MyClass&, A::MyClass&) but the second will not compile because swap(obj1, obj2) would be ambiguous.

如果是函数重载,为什么我的swap(Bar& a, Bar& b) 没有有他描述的歧义问题?他错了吗?


如果 2. 为真,根据 C++ Primer 5th 18.2.3:

std::cin >> s;

is equivalent to:

operator>>(std::cin, s);

In this example, when the compiler sees the “call” to operator>>, it looks for a matching function in the current scope, including the scopes enclosing the output statement. In addition, because the >> expression has parameters of class type, the compiler also looks in the namespace(s) in which the types of cin and s are defined. Thus, for this call, the compiler looks in the std namespace, which defines the istream and string types. When it searches std, the compiler finds the string output operator function.

因此名称查找顺序是:当前范围 --> 封闭范围 --> 参数命名空间范围

那为什么 std::swap 不隐藏自定义 swapusing std::swapstd::swap 引入当前作用域,它具有更高的查找优先级。


我的两个假设在某些部分似乎都是无效的,我感到很困惑。需要一些帮助。提前致谢。

最佳答案

1. 为真。对于 ADL ,

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.

std::swap 是通过通常的非限定名称查找找到的,而 Foo::swap 是通过 ADL 找到的,它们都在重载集中。 Foo::swap 是一个非模板函数,优先于 std::swap ,它是 overload resolution 中的模板。 .

F1 is determined to be a better function than F2 if implicit conversions for all arguments of F1 are not worse than the implicit conversions for all arguments of F2, and

...

4) or, if not that, F1 is a non-template function while F2 is a template specialization

关于链接答案中的引述,

if for some reason both A::swap(A::MyClass&, A::MyClass&) and std::swap(A::MyClass&, A::MyClass&) are defined,

其实没有std::swap(A::MyClass&, A::MyClass&),这只是一个假设,如果有一个非模板std::swap(A::MyClass&, A::MyClass&) 那么调用将是不明确的 ...

关于c++ - ADL 名称查找问题,正在使用 std::swap; swap(a,b) 与函数重载或内部作用域函数隐藏外部作用域函数有关?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61699806/

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