C++成员函数&/&&引用限定符与旧风格写法等价性问询
C++成员函数引用限定符行为说明
基础语法规则
- C++11及后续标准支持为成员函数添加引用限定符,可用限定符包含
&、const&、&&等组合,作用是约束成员函数可绑定调用的对象实例的值类别。 - 重载约束:如果同一个成员函数名的多个重载中,至少有一个重载添加了引用限定符,那么其余所有同签名的重载都必须添加对应的引用限定符,否则会触发编译错误。
C++11标准前的无引用限定写法
struct A { void f() const {} // #1 const版本,可被const实例调用 void f() {} // #2 无限定非const版本 };
C++11及后续标准的带引用限定规范写法
struct A { void f() const& {} // #3 const左值引用限定,仅可被const左值实例调用 void f() & {} // #4 非const左值引用限定,仅可被非const左值实例调用 // void f() && {} // 右值引用限定版本,可根据业务需求按需添加 };
常见认知误区
很多开发者默认带&限定的非const成员函数(即上述#4),和C++11之前无引用限定的非const成员函数(上述#2)行为完全等价,实际上二者存在明确差异,可通过如下测试代码验证:
struct A { void f() & {} // void f() && {} // 注释右值引用限定版本用于对比测试 }; struct B { void f() {} // 旧风格无引用限定的非const成员函数 }; int main() { A{}.f(); // 编译报错:右值实例无法匹配仅带&限定的重载,调用会丢弃右值限定 B{}.f(); // 编译通过 }
问题解答
针对提出的两个判断,结论如下:
- 第一个判断基本成立:旧风格编写的无修饰(非const、无引用限定)成员函数,确实可以同时匹配左值、右值两类实例的调用,行为上等价于同时定义了同实现的
&版本和&&版本重载。即如下旧写法:
struct B { void f() { /* 业务逻辑实现 */ } };行为等价于:
struct B { void f() & { /* 与旧写法完全一致的业务逻辑 */ } void f() && { /* 与旧写法完全一致的业务逻辑 */ } }; - 第二个判断不成立:上述等价关系,不等同于
&&重载内部转调&重载的写法,即和如下实现语义有差异:
二者核心差异为:原生无引用限定的成员函数被右值实例调用时,函数体内的struct B { void f() & { /* 业务逻辑实现 */ } void f() && { return f(); } };*this值类别为右值;而转调写法中,进入&版本的重载后,*this为左值,会影响函数内部其他带引用限定接口的重载匹配结果,二者语义不完全一致。
内容的提问来源于stack exchange,提问作者alfC
相关产品推荐
相关产品推荐

