为什么非限定名称查找会查找所有重载的声明

时间:2014-06-01 04:34:30

标签: c++ overloading language-lawyer

这是一个例子,我试图理解非限定名称如何查找重载声明的工作:

int foo(char a){ return 0; }

namespace A
{
    int foo(int a){ return a; }
    int foo(){ return 2; }
    extern int j;
    extern int i;
}

int A::j=foo('a'); //97
int A::i=foo(); //2

这意味着找不到通过非限定名称查找的int foo(char);,但可以找到int foo(int);int foo()。因此,我认为只要找到名称的所有重载声明,非限定名称就会查找重载声明结束。我无法找到标准,我只能找到以下内容(秒。 3.4.1):

  只要找到名称的声明,

名称查找就会结束。

这句话没有说明重载声明的查询。

4 个答案:

答案 0 :(得分:2)

您将名称查找重载决策混合在一起。没有"不合格的名称会查找重载的声明"。名称查找和重载解析是分开的。

名称查找意味着确定找到名称的范围。完成后,重载决议确定应该使用该范围中可见的哪些声明。< / p>

在您的代码中,名称查找确定foo表示A::foo。然后重载决策A::foo()A::foo(int)之间进行选择。 ::foo不考虑重载解析,因为它不是A::foo的定义。

另一个例子:

namespace C { void f(); }
namespace B { void f(); void f(float); }
namespace C { void f(long); }

using namespace C;

int main()
{
    f(1.0);
}

处理行f(1.0)时,名称查找会看到void f();并停止。结果是f表示C::f

然后重载决策启动,C::f的所有声明都被认为是重载解析。选择void f(long)

答案 1 :(得分:1)

  

declarator-id qualified-id 的声明中,声明 qualified-id 之前使用的名称      在定义的命名空间范围中查找;在范围内查找 qualified-id 后面的名称         成员的类或命名空间。

(C ++11§3.4.3/ 3)

所以

int A::j=foo('a');
int A::i=foo();

foo范围内查找名称A只是因为您在声明者的左侧有A::jA::i

请注意,如果你这样做

int k = foo();

只会找到全局foo,您将收到错误。

答案 2 :(得分:0)

你说

  

这意味着找不到通过非限定名称查找的int foo(char);,但可以找到int foo(int);int foo()。因此,我认为只要找到名称的所有重载声明,非限定名称就会查找重载的声明。

another SO post

中提出了类似的问题

从3.4.1 / 14开始:

  

如果命名空间的变量成员在其命名空间的范围之外定义,那么查找成员定义中出现的任何名称(在declarator-id之后),就好像该成员的定义发生在其命名空间。

您发布的代码相当于:

int foo(char a){ return 0; }

namespace A
{
    int foo(int a){ return a; }
    int foo(){ return 2; }
    extern int j;
    extern int i;
}

namespace A
{
  int j=foo('a');
  int i=foo();
}

当定义和初始化放在命名空间下时,很明显为什么首先在命名空间A中查找用于初始化变量的函数。如果可以为命名空间A中的函数找到明确的匹配,则搜索它将停止。这意味着,在编译行时,

int A::j=foo('a');

foo的查找从名称空间A开始,已解析为int A::foo(int);,搜索foo停止。

希望这可以解决这个困惑。

答案 3 :(得分:-1)

在标准(§3.4/ 1)

  

名称查找应   找到一个明确的名称声明(见10.2)。如果名称查找名称是函数名称,则名称查找可以将多个声明与名称相关联;据说声明形成一套   重载函数(13.1)。名称查找成功后,将发生重载分辨率(13.3)。   访问规则(第11条)仅被视为名称查找和函数重载解析(如果   适用)已成功。

这意味着方法的步骤如下:

  1. 首先收集所有匹配的名称
  2. 执行重载决议
  3. 检查辅助功能
  4. 对于方法,在找到第一个匹配后,名称查找不会返回,而是搜索所有匹配的名称。从语句中可以清楚地看到,如果名称查找的名称是函数名称 ,则名称查找可能会将多个声明与名称相关联。