c ++内联好友函数会导致名称空间之间的名称隐藏吗?

j_k*_*bik 3 c++

考虑以下代码:

namespace Foo1 {
void add( int ) {}
void subtract( int ) {}
}

namespace Foo2 {


    class Bar {
    public:
        friend void add( Bar ) {}
    };

    void subtract( Bar ) {}

    void xxx() {
        int i = 0;
        using namespace Foo1;
        add( i );  // Is this an error or not?
        subtract( i ); // This is an error due to name hiding
    }
}
Run Code Online (Sandbox Code Playgroud)

在中,Foo2::xxx()我使用using命名空间来访问Foo1::addFoo1::subtract。调用减法显然是一个错误,因为Foo2::subtract 隐藏名称。但是Foo2::add不应真正可见,Foo2因为只能使用ADL找到它,并且不应隐藏Foo1::add。我的理解正确吗?

我已经在多个版本的MSVC和gcc上尝试了上面的代码。前者一直拒绝add(i)通话,但是错误消息对我来说并不明确。后者一直接受它。以下哪一项(如果有)是正确的?

Sto*_*ica 5

我认为海湾合作委员会就在这里。

[namespace.memdef](重点是我的)

3如果非本地类中的好友声明首先声明了一个类,函数,类模板或函数模板,则该好友是最内层的命名空间的成员。朋友声明本身不会使名称对不合格查找([basic.lookup.unqual])或合格查找([basic.lookup.qual])可见。[?注:如果在名称空间范围内(在授予友谊的类定义之前或之后)提供了匹配的声明,则朋友的名称将在其名称空间中可见。?-?end note?]如果调用了朋友函数或函数模板,则可以通过名称查找来找到其名称,该名称查找考虑了与函数参数类型相关联的名称空间和类中的函数([basic.lookup.argdep]) 。

因此,不合格add( i )的对象本身不应找到的声明add( Bar ),这意味着查找应继续并考虑using指令引入的名称。而且由于参数不是类类型的,因此ADL是不可能的。我断定那add( Bar ) 不应该隐藏add( int )