You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中String()构造函数是左值还是右值?代码输出疑惑求解

问题与解答:右值引用与成员函数重载匹配

代码定义

String类定义

class String
{
public:
  String() { }
  ...
  void test() && { std::cerr << "right version" << std::endl; }
  void test() & { std::cerr << "left version" << std::endl; }
  void test_ctor(String &&s) { std::cerr << "right version" << std::endl; }
  void test_ctor(const String &s) { std::cerr << "left version" << std::endl; }
  ...
private:
  ...
};

main.cpp代码

int main() 
{
  String().test();
  String lhs;
  lhs.test();

  ([]() -> String { return String(); })().test();

  lhs.test_ctor(lhs);
  lhs.test_ctor(String());
}

运行输出

right version
left version
right version
left version
left version

对应代码行的输出注释:

String().test(); // right version
String lhs;
lhs.test(); // left version

([]() -> String { return String(); })().test(); // right version

lhs.test_ctor(lhs); // left version
lhs.test_ctor(String()); // left version

核心疑问

String()调用test()时匹配右值版本,但作为test_ctor的参数时却匹配const String&版本,输出left version,原因是什么?String()是左值还是右值?


解答

  1. String()是右值:直接调用构造函数创建的临时对象属于纯右值(prvalue),是右值的一种。

  2. 成员函数重载匹配规则(test()的情况):
    C++11及以后支持引用限定符(&和&&)来重载成员函数:

    • void test() &:仅能被左值对象调用,&限定符表示函数仅对左值实例可用。
    • void test() &&:仅能被右值对象调用,&&限定符表示函数仅对右值实例可用。
      所以String().test()中,临时对象是右值,匹配test() &&版本;lhs.test()中lhs是左值,匹配test() &版本。
  3. 函数参数匹配规则(test_ctor的情况):
    核心原因是test_ctor(String &&s)是非const的右值引用参数,而当临时对象无法被绑定到该参数时,编译器会退而选择const String&版本:

    • const String&是兼容性极强的参数类型,可以绑定左值、右值、临时对象等所有类型的String表达式。
    • 如果你的类中存在阻止移动语义生效的情况(比如显式声明了拷贝构造函数但未声明移动构造函数,导致编译器不生成默认移动构造;或是移动构造函数被设为private),临时对象无法被绑定到非const的右值引用,编译器就会优先匹配const String&版本。

内容的提问来源于stack exchange,提问作者Wiosier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 05:17:06