abr*_*bra 15 c++ language-lawyer c++11
考虑这个课程:
class Base{
public:
void func(double a) = delete;
void func(int a) const {}
};
int main(){
Base base;
base.func(1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用clang ++编译时,会产生以下错误:
clang++ --std=c++11 test.cpp
test.cpp:22:7: error: call to member function 'func' is ambiguous
base.func(1);
Run Code Online (Sandbox Code Playgroud)
使用g ++,会产生一个警告:
g++ -std=c++11 test.cpp
test.cpp: In function ‘int main()’:
test.cpp:22:13: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: base.func(1);
Run Code Online (Sandbox Code Playgroud)
为什么这段代码含糊不清?
Pio*_*cki 14
非静态成员函数,如下两个:
void func(double); // #1
void func(int) const; // #2
Run Code Online (Sandbox Code Playgroud)
还接受一个隐式对象参数,该参数在重载决策([over.match]/p1)中被视为任何其他参数:
过载分辨率是一种机制,用于在给定作为调用参数的表达式列表和可根据调用上下文调用的一组候选函数的情况下选择要调用的最佳函数.最佳函数的选择标准是参数的数量,参数与候选函数的参数类型列表匹配的程度,对象与隐式对象参数的匹配程度(对于非静态成员函数)以及某些其他函数候选函数的属性.
在将隐式对象参数合并到成员函数签名之后,编译器会看到两个重载:
void func(Base&, double); // #1
void func(const Base&, int); // #2
Run Code Online (Sandbox Code Playgroud)
并尝试根据调用选择最佳可行功能:
Base base;
base.func(1);
Run Code Online (Sandbox Code Playgroud)
从base(类型的非常量左值Base)转换为Base&具有精确匹配等级(直接引用绑定产生身份转换) - 请参阅表13.从转换base到const Base&是也完全匹配排名,但是,[over.ics.rank] /p3.2.6声明#1有一个更好的转换序列:
- S1和S2是引用绑定([dcl.init.ref]),引用引用的类型除了顶级cv限定符之外是相同的类型,S2引用的引用所引用的类型是比由S1初始化的引用所引用的类型更多的cv限定.[ 例如:
Run Code Online (Sandbox Code Playgroud)int f(const int &); int f(int &); int g(const int &); int g(int); int i; int j = f(i); // calls f(int &) int k = g(i); // ambiguous
现在对于第二个参数,从积分prvalue 1转换double为浮动积分转换([conv.fpint]),它被赋予转换等级.另一方面,1to int是具有精确匹配等级的身份转换.对于这个论点,被认为有更好的转换序列([over.ics.rank] /p3.2.2):#2
- S1的等级优于S2的等级,或者S1和S2具有相同的等级,并且可以通过以下段落中的规则区分,或者,如果不是,[...]
要成功的重载分辨率要求最多存在一个转换序列不同的参数([over.match.best]):
给定这些定义,如果对于所有自变量i,可行函数F1被定义为比另一个可行函数F2更好的函数,ICS i(F1)不是比ICS i(F2)更差的转换序列,然后
- 对于某些参数j,ICS j(F1)是比ICS j(F2)更好的转换序列,或者,如果不是,[...]
这里,ICS 0(#1)优于ICS 0(#2),但ICS 1(#2)优于ICS 1(#1),因此编译器无法在两个重载之间进行选择.检测歧义.
| 归档时间: |
|
| 查看次数: |
4288 次 |
| 最近记录: |