加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 使用声明隐藏名称

发布时间:2020-12-16 10:02:02 所属栏目:百科 来源:网络整理
导读:#include iostreamstruct 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) 在上面的代码
#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类中没有可用的带有两个参数的交换函数.

我在这里有一个问题.在我看来,在我使用了使用声明之后 – 使用std :: swap,它只是使std :: swap – STL中的模板函数可见.所以我认为应该在H :: swap()中调用STL中的swap.但结果表明,调用了空隙交换(H& t1,H& t2).

所以这是我的问题:

>为什么我不能在没有使用声明的情况下调用swap?(我想这是因为在类中没有带有两个参数的交换函数.但我不确定.)
>为什么要调用我的定义的交换而不是H :: swap中的STL交换?

解决方法

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

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

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

不合格的交换找到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. […]

由于非限定查找集找到类成员,因此依赖于参数的查找集为空(即,它找不到交换(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(),因为前者是在更内部的范围内声明的.使用std :: swap;不符合上述规则中任何会导致Y为空的标准(它不是类成员,它是一个using声明,它是一个函数模板).因此,依赖于参数的查找集确实包括在相关命名空间中找到的声明 – 其中包括交换(H&,H&)(因为H在全局命名空间中).我们最终得到了两个重载候选者 – 而你的首选是非首选,因为它是非模板.

有关将swap添加到您的类的首选方法,请参阅Xeo’s answer.基本上,你想写:

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

这将由ADL(仅由ADL)发现.然后每当有人调用swap正确时:

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

Lookup会在适当的时候找到你的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读