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

C++中对象初始化与值计算的区别是什么?结合标准条文说明

引自《C++编程语言标准工作草案》[basic.lval/5]:
glvalue的结果是表达式所指代的实体。prvalue的结果是表达式存储到其上下文中的值;类型为cv void的prvalue没有结果。结果为值V的prvalue有时被称为持有或命名值V。prvalue的结果对象是由该prvalue初始化的对象;用于计算内置运算符操作数的值的非丢弃prvalue,或类型为cv void的prvalue没有结果对象。
[注4:除非prvalue是decltype-specifier的操作数,否则类类型或数组类型的prvalue始终有一个结果对象。对于类型不是cv void的丢弃prvalue,会物化一个临时对象,参见[expr.context]。——注结束]

核心区别

二者的核心差异在于执行目标和prvalue的处理逻辑:

  • 值计算的目标是得到表达式的结果值,仅关注prvalue持有的值本身,不需要关联到具体的对象存储,完成值提取后prvalue不需要对应结果对象。
  • 对象初始化的目标是构造/赋值一个实际存在的对象实体,此时prvalue必须绑定到对应的结果对象,直接将值写入该对象的存储空间,不需要额外产生中间临时对象。

示例说明

1. 值计算场景

int a = 10;
int b = a + 20;

上述代码中,a + 20是int类型的prvalue,作为内置加法运算符的操作数参与值计算,只需要提取它持有的结果值30即可,不需要创建对应的结果对象,符合标准中"用于计算内置运算符操作数的值的非丢弃prvalue没有结果对象"的规定。

再举一个值计算的例子:

bool is_greater = 15 > 6;

这里15 > 6的prvalue仅用于值计算得到布尔值true,不需要对应的结果对象,只需要取结果值参与赋值即可。

2. 对象初始化场景

#include <string>
std::string s = std::string("hello world");

上述代码中,prvalue std::string("hello world")的结果对象就是左值s,prvalue持有的值直接写入s的存储空间,不会产生中间临时对象,也不需要调用移动/拷贝构造函数,完全符合标准中prvalue的结果对象是被其初始化的对象的规定。

再比如丢弃prvalue的场景:

std::string("temp_test");

按照标准注4的说明,这种丢弃的非void类型prvalue会物化一个临时对象作为该prvalue的结果对象,属于对象初始化范畴,临时对象会在当前语句结束后销毁。


内容的提问来源于stack exchange,提问作者Géry Ogam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 20:57:02