Pio*_*ycz 8 c++ gcc argument-dependent-lookup
我有以下简化代码
namespace Namespace
{
int foo() { return 1; }
class Class
{
public:
int foo() const { return 2; }
class Nested {
public:
Nested()
{
cout << foo() << endl;
}
};
};
}
Run Code Online (Sandbox Code Playgroud)
我收到了这个错误:
错误:无法调用成员函数'int Namespace :: Class :: foo()const'没有对象:
cout << foo() << endl;
^^^^^
Run Code Online (Sandbox Code Playgroud)
似乎编译器选择非静态int Namespace::Class::foo() const而不是全局函数int Namespace::foo().
但是如何能够在没有对象的情况下调用来自其他类的非静态函数呢?Nested object无法访问周围环境 Class object- 毕竟这不是Java.
我通过cppreference的重载解析仔细阅读,我找不到这种行为的基本原理.我更怀疑这是gcc错误.
只是第二个问题的答案.解决方法很简单,需要告诉编译器存在这样的全局函数:
Nested()
{
using Namespace::foo; //< workaround: inform compiler such function exists
cout << foo() << endl;
}
Run Code Online (Sandbox Code Playgroud)
顺便说一下,解决方法是否正确?还有更好的解决方案吗?
我通过cppreference的重载解析仔细阅读,我找不到这种行为的基本原理.你能指出导致这种行为的语言规则吗?
在重载解析过程选择最佳可行函数之前,在名称查找阶段期间生成初始候选集.换句话说,应在Name查找部分中搜索预期的行为,而不是在Overload resolution one中搜索.
C++标准中描述了非限定名称的名称查找过程:
§3.4.1[basic.lookup.unqual]/p8:
X在函数的declarator-id之后的类的成员函数(9.3)的定义中或在类的非静态数据成员(9.2)的brace-or-equal-initializer中使用的名称X应在其中一个中声明.以下方式:- 在其使用的块中或在封闭块(6.3)中使用之前,或
- 应为X类成员或X(10.2)基类的成员,或
- 如果
X是类Y(9.7)的嵌套类,则应该是Y基类的成员,或者应该是基类的成员Y(此查找依次应用于Y封闭类,从最内层的封闭类开始),或者[ ...]
并且只有在仍未找到的情况下:
-如果
X是命名空间中的一员N,或者是一个嵌套类一类是的成员N,或者是局部类或局部类的函数是成员内的嵌套类N,使用名称的前,在命名空间N或其中一个N封闭的命名空间中.
由于名称查找在找到名称后立即结束(§3.4.1[basic.lookup.unqual]/p1):
在3.4.1中列出的所有情况下,在每个相应类别中列出的顺序中搜索范围; 一旦找到名称的声明,名称查找就会结束.
在您的情况下,int foo() const { return 2; }遇到任何其他范围都不会被搜索.
解决方法很简单,需要告诉编译器存在这样的全局函数:
Run Code Online (Sandbox Code Playgroud)using Namespace::foo; //< workaround: inform compiler such function exists这种解决方法是否正确?
§7.3.3[namespace.udecl]/p1:
甲using声明引入了一个名称到其中所述声明性区域使用声明出现.
§3.3.1[basic.scope.declarative]/p1:
每个名称都在程序文本的某些部分中引入,称为声明性区域,该声明区域是该名称有效的程序的最大部分,也就是说,该名称可以用作非限定名称以引用同一实体.
引入带有using声明的名称会影响非限定名称查找,使得它在第一步中找到该函数,即该名称变为声明:
- 在其使用的块中或在封闭块中使用之前(6.3)
还有更好的解决方案吗?
在从某个命名空间作用域引用函数时,可以使用限定名称,明确指出要引用的符号:
Nested()
{
cout << Namespace::foo() << endl;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
416 次 |
| 最近记录: |