C++ 过载解决方案:这怎么不含糊?

C++ 过载解决方案:这怎么不含糊?,c++,language-lawyer,overload-resolution,C++,Language Lawyer,Overload Resolution,假设我们有这个代码,从一个单独的问题复制过来: namespace x { void f() { } class C { void f() { using x::f; f(); // <== } }; } 名称空间x { void f() { } C类 { void f() { 使用x::f; f();//因为使用声明将x

假设我们有这个代码,从一个单独的问题复制过来:

namespace x 
{
    void f()
    {
    }

    class C 
    {
        void f() 
        {
            using x::f;
            f();         // <==
        }
    };
}
名称空间x
{
void f()
{
}
C类
{
void f()
{
使用x::f;

f();//因为
使用
声明将
x::f
带入
f
的范围,该范围比
C
的范围窄。非限定查找考虑本地块范围,查找匹配项,并在考虑更宽的类范围之前停止。由于没有函数,因此没有依赖于参数的查找参数,因此不考虑进一步的作用域。

@MikeSeymour的答案非常准确;以下是相关的标准引用(C++11,重点):

13.3.1.1.1/3:

在非限定函数调用中,名称不是由
->
运算符限定的,它具有更一般的形式 在函数调用的上下文中按照常规规则查找名称 用于函数调用中的名称查找(3.4)。通过该查找找到的函数声明构成 候选函数。由于名称查找规则,候选函数集完全由(1)个 非成员函数或(2)某些类的全部成员函数

3.4.1/1:

在3.4.1中列出的所有情况下,都会按照每个 各自的类别;一旦找到名称的声明,名称查找就会结束。如果未找到任何声明 如果发现,程序的格式不正确

3.4.1/8

在函数的声明符id之后定义类
X
的成员函数(9.3)时使用的名称 …应以下列方式之一声明: 以下方法:

  • 在其所在区块或封闭区块(6.3)中使用之前,或
  • 应为
    X
    类成员或
    X
    (10.2)基类成员,或

从3.4.1/8中,我们看到名称
f
的声明(例如使用x::f的声明
)在使用的块中,比 f>代码>早,作为类<代码> c>代码>的成员。按3.4.1/1,选择较早的一个,因此整个查找可以通过< <代码> >声明>代码> > < /p> < p>。我认为C++标准的这些引用将是相关的:

<> >从C++标准(7.3.3使用声明)

13由于使用声明是一种声明,因此 在同一声明区域中具有相同名称的声明(3.3) 也适用于使用声明

和(3.3.7类别范围)

4) 在成员函数中声明的名称隐藏了 其作用域扩展到或超过成员末尾的名称 函数的类