我有下一个代码:
void f(int){}
struct A
{
void f()
{
f(1);
}
};
Run Code Online (Sandbox Code Playgroud)
此代码与错误消息(GCC)格式不正确:error: no matching function for call to ‘A::f(int)’或(clang)Too many arguments to function call, expected 0, have 1; did you mean '::f'?
为什么我需要使用::与成员函数同名的非成员函数,但具有不同的签名?这个要求的动机是什么?
我认为编译器应该能够弄明白我想调用非成员函数,因为签名是不同的(clang甚至把它放在错误消息中!).
请不要将其标记为重复 - 这是一个不同的问题,这个在C++中调用一个类中的非成员函数,具有相同的方法
Mik*_*our 23
为什么我需要使用::来调用与成员函数同名但具有不同签名的非成员函数
因为那些是规则.嵌套作用域中的名称会在更宽的作用域中隐藏具有相同名称的实体.
这个要求的动机是什么?
考虑成员函数调用具有不完全匹配的签名的另一个成员的情况:
struct A {
void f(double);
void g() {f(42);} // requires int->double conversion
};
Run Code Online (Sandbox Code Playgroud)
现在假设有人在周围的命名空间中添加了一个不相关的函数
void f(int);
Run Code Online (Sandbox Code Playgroud)
如果这包含在范围内的重载集中A,那么突然行为A::g会改变:它会调用它而不是A::f.将过载集限制在最窄的可用范围内可以防止出现这种意外破坏.
正如您(以及您的有用编译器)所说,如果您需要,外部名称仍然可用(具有资格).
编译器执行非限定名称查找,f在§3.4.1[basic.lookup.unqual]中指定(幸运的是,这里没有ADL):
1在3.4.1中列出的所有情况下,在每个相应类别中列出的顺序中搜索范围; 一旦找到名称的声明,名称查找就会结束.如果没有找到声明,该程序就是格式错误.
8对于类
X的成员,在成员函数体中使用的名称,在缺省参数中,在异常规范中,在非静态数据成员(9.2)的 brace-or-equal-initializer中,或者在在成员的declarator-id之后,X定义之外的类成员的定义应以下列方式之一声明:
- 在用于使用它的块中或在封闭块(6.3)中使用之前,或
- 应是班级成员
X或是X(10.2)基类的成员,或- if
X是类Y(9.7)的嵌套类,应该是Y或者应该是基类的成员Y(这个查找依次应用于Y封闭类,从最内层的封闭类开始),或者- if
X是本地类(9.8)或者是本地类的嵌套类,在包含类定义的X块中定义类之前X,或者- if
X是名称空间N的成员N,或者是N在使用名称之前是类的成员的类的嵌套类,或者是属于其成员的函数的本地类中的本地类或嵌套类,在命名空间N或其中一个N封闭的命名空间中.
一旦找到声明,名称查找就会停止.因此,一旦它f()在第二个子弹点找到该成员,它就会停止并且从不在其他地方搜索.
在重载解析时,在名称查找之后完成拒绝不存活的函数.
| 归档时间: |
|
| 查看次数: |
1847 次 |
| 最近记录: |