C++中&&是否属于限定符?编译器报错引发的技术疑问
关于C++成员函数右值引用限定符的疑问解答
先看你给出的无法编译的代码:
#include <string> class Dummy { std::string member{"test"}; public: std::string const && foo() && { return std::move(member); } }; int main() { Dummy d; std::string s = d.foo(); }
对应的编译器报错:
<source>: In function 'int main()': <source>:14:26: error: passing 'Dummy' as 'this' argument discards qualifiers [-fpermissive] 14 | std::string s = d.foo(); | ~~~~~^~ <source>:7:26: note: in call to 'const std::string&& Dummy::foo() &&' 7 | std::string const && foo() && |
下面针对你的疑问逐一解答:
1. 成员函数后的&&是否属于限定符?
不属于C++标准定义的cv限定符(cv限定符仅指const和volatile)。
2. 它的官方定义是什么?
它是成员函数引用限定符,C++11引入的语法。引用限定符分为两种:
&:限定成员函数只能被左值对象调用&&:限定成员函数只能被右值对象调用
作用是精准控制成员函数的调用场景,避免左值对象误用仅针对右值设计的逻辑。
3. 编译器提示“丢弃限定符”的原因,以及如何让代码编译通过?
这个报错属于GCC的提示表述不够精准——实际不存在“丢弃cv限定符”的操作,问题本质是:你用左值对象d调用了仅允许右值对象调用的foo()函数,编译器无法将左值类型的this指针(指向左值d)转换为右值引用类型的this,因此报错。
要让代码编译通过,不需要“丢弃”任何内容,只需满足函数的调用条件,有两种常见方案:
- 将左值对象转为右值后调用:
std::string s = std::move(d).foo(); - 给
foo()添加左值引用限定符的重载版本,允许左值对象调用:// 新增左值重载 std::string const && foo() & { return std::move(member); }
内容的提问来源于stack exchange,提问作者Thomas W.
相关产品推荐
相关产品推荐

