Name hiding by using declaration

天大地大妈咪最大 提交于 2019-12-03 20:22:25
Barry
  1. Why can't I invoke swap without a using declaration?

We start in the nearest enclosing scope and work our way outwards until we find something. With this:

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

Unqualified swap finds H::swap(). Then we do argument-dependent lookup. But the rule there is, from [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. [...]

Since the unqualified lookup set finds a class member, the argument-dependent lookup set is empty (that is, it doesnt find swap(H&, H&)).

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

When you add:

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

now unqualified swap finds std::swap() and not H::swap(), since the former is declared in a more inner scope. using std::swap; does not match any of the criteria in the above-stated rule that would lead to Y being empty (it's not a class member, it is a using-declaration, and it is a function template). As a result, the argument-dependent lookup set does include declarations found in associated namespaces - which includes swap(H&, H&) (since H is in the global namespace). We end up with two overload candidates - and yours is preferred since it's the non-template.


See Xeo's answer on the preferred way to add swap to your class. Basically, you want to write:

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

This will be found by ADL (and only by ADL). And then whenever anybody calls swap correct:

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

Lookup will find yours where appropriate.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!