考虑以下代码:
#include <iostream>
using namespace std;
struct A {
void f() { cout << "A::f" << endl; }
void f() const { cout << "A::f const" << endl; }
};
struct B {
void f() & { cout << "B::f &" << endl; }
void f() const & { cout << "B::f const &" << endl; }
};
A getA() { return A{}; }
B getB() { return B{}; }
int main() {
getA().f();
getB().f();
}
Run Code Online (Sandbox Code Playgroud)
打印
A::f
B::f const &
Run Code Online (Sandbox Code Playgroud)
因为B,选择了const重载,而不是非常量重载.我想这意味着为*this指定左值ref限定符与不指定任何内容有所不同.这是为什么?"隐含此参数"是否会改变类型,而const重载现在成为重载解析的更好选择?
use*_*016 19
在这种情况下:
struct A {
void f() { cout << "A::f" << endl; }
void f() const { cout << "A::f const" << endl; }
};
getA().f();
Run Code Online (Sandbox Code Playgroud)
两种重载都是可行的f,但非常量的重载是优选的,因为它不需要转换.
但在这种情况下:
struct B {
void f() & { cout << "B::f &" << endl; }
void f() const & { cout << "B::f const &" << endl; }
};
getB().f();
Run Code Online (Sandbox Code Playgroud)
第一个重载需要this是左值.但是getB().f(),结果getB()是一个prvalue,它不能绑定到非const的左值.所以这种过载是不可行的,也没有选择.
然而,第二个重载需要this是一个const值,prvalue可以绑定到:这个重载是可行的并由编译器选择.
作为参考,完全误导我的句子是[over.match.funcs]N3337的§13.3.1/ 4:
- 对于非静态成员函数,隐式对象参数的类型是
- 对于没有引用限定符或使用&ref-qualifier声明的函数的"对cv X的左值引用"
- 对于用&& ref-qualifier声明的函数的"对cv X的rvalue引用"
(强调我的).
所以我对为什么输出有所不同感到有点疯狂.没有或有一个&ref限定符应该根据这里相同,对吧?
那么,原因是之后在§13.3.1/ 5中潜入了一条额外的规则
对于未使用ref-qualifier声明的非静态成员函数,应用其他规则:
- 即使隐式对象参数不是const限定的,只要在所有其他方面都可以将参数转换为隐式对象参数的类型,就可以将rvalue绑定到参数.
这基本上触发了非const rvalue到非const lvalue转换,并在上面的例子中产生了所有不同.D'呃.
| 归档时间: |
|
| 查看次数: |
535 次 |
| 最近记录: |