gpt4 book ai didi

c++ - 使用声明隐藏名称

转载 作者:太空狗 更新时间:2023-10-29 20:10:55 25 4
gpt4 key购买 nike

#include <iostream>

struct H
{
void swap(H &rhs);
};

void swap(H &, H &)
{
std::cout << "swap(H &t1, H &t2)" << std::endl;
}

void H::swap(H &rhs)
{
using std::swap;
swap(*this, rhs);
}


int main(void)
{
H a;
H b;

a.swap(b);
}

这是结果:

swap(H &t1, H &t2)

在上面的代码中,我尝试定义一个H的交换函数。在函数 void H::swap(H &rhs) 中,我使用 using 声明使名称 std::swap 可见。如果没有 using 声明,则无法编译代码,因为 H 类中没有可用的带两个参数的交换函数。

我有一个问题。在我看来,在我使用 using 声明 -- using std::swap 之后,它只是使 std::swap -- STL 中的模板函数可见。所以我认为应该在H::swap()中调用STL中的swap。但结果显示调用了 void swap(H &t1, H &t2)

所以这是我的问题:

  1. 为什么我不能在没有using声明的情况下调用swap?(我猜是因为类中没有带两个参数的swap函数。但我不确定。)
  2. 为什么会调用我定义的交换而不是 H::swap 中的 STL 交换?

最佳答案

  1. Why can't I invoke swap without a using declaration?

我们从最近的封闭范围开始,向外工作,直到找到某些东西。有了这个:

void H::swap(H &rhs)
{
swap(*this, rhs);
}

非限定 swap 查找 H::swap()。然后我们进行参数依赖查找。但规则是,来自 [basic.lookup.argdep] :

Let X be the lookup set produced by unqualified lookup (3.4.1) and let Y be the lookup set produced by argument dependent lookup (defined as follows). If X contains
— a declaration of a class member, or
— a block-scope function declaration that is not a using-declaration, or
— a declaration that is neither a function or a function template
then Y is empty. Otherwise Y is the set of declarations found in the namespaces associated with the argument types as described below. [...]

由于非限定查找集找到了一个类成员,因此依赖于参数的查找集为空(即,它没有找到swap(H&, H&))。

  1. Why will the swap of my definition be invoked instead of the STL swap in the H::swap?

添加时:

void H::swap(H &rhs)
{
using std::swap;
swap(*this, rhs);
}

现在不合格的 swap 找到 std::swap() H::swap(),因为前者是在更内部的范围内声明的。 using std::swap; 不符合上述规则中的任何条件,这将导致 Y 为空(它不是类成员,它 一个using-declaration,它是一个函数模板)。因此,依赖于参数的查找集确实包含在关联命名空间中找到的声明 - 其中包括 swap(H&, H&)(因为 H 在全局命名空间中)。我们最终有两个过载候选者——你的是首选,因为它是非模板。


参见 Xeo's answer关于将交换添加到您的类(class)的首选方式。基本上,你想写:

struct H {
friend void swap(H&, H&) { ... }
};

这将由 ADL 找到(并且只能由 ADL 找到)。然后每当有人调用时交换正确:

using std::swap;
swap(a, b);

查找会在适当的地方找到您的。

关于c++ - 使用声明隐藏名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35894955/

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