C++隐式构造与结构体初始化:两种MyStruct1赋值是否等价?
两种
MyStruct1赋值写法的等价性与底层逻辑 针对你给出的代码定义,两种写法的最终执行结果完全等价,但背后的运行逻辑并非仅靠隐式构造函数就能覆盖。
两种写法的实际执行流程
- 写法2为完全显式执行路径:
- 通过
MyStruct1{true}直接构造一个持有myBool1=true、myBool2=true的临时MyStruct1右值 - 调用
MyStruct1隐式生成的逐成员移动赋值运算符,将临时对象的内容写入左侧的myStruct1成员
- 通过
- 写法1的执行路径:
- 编译器首先检测到左侧
myStruct1为MyStruct1类型,右侧传入的true为bool类型,不存在匹配该类型组合的直接赋值重载 - 触发用户定义隐式转换规则:调用单参数的
MyStruct1(bool val)构造函数,将true转换为一个和写法2完全一致的临时MyStruct1右值 - 后续调用移动赋值运算符写入成员的流程和写法2没有任何区别
- 编译器首先检测到左侧
核心规则澄清
你提到的隐式构造函数机制,只是写法1流程中的一环,整个赋值过程还依赖两个配套的C++核心规则才能跑通:
- 类的非
explicit单参数构造函数,会自动参与从参数类型到类类型的隐式转换序列 - 类在没有自定义拷贝/移动赋值运算符的场景下,会自动生成逐成员拷贝的默认赋值运算符,用于接收同类型的临时对象
- 无论类是否自定义赋值运算符,只要隐式转换生成的临时对象和显式构造的对象内容一致,两种写法最终都会走到同一个赋值处理逻辑里,不会出现行为分叉。
边界差异说明
- 如果给
MyStruct1(bool val)构造函数加上explicit修饰,写法1会直接触发编译错误——因为explicit会禁止该构造函数参与隐式转换,此时就只能通过写法2的显式构造方式完成赋值。 - 仅在类存在多个可触发隐式转换的重载构造函数时,两种写法才可能出现结果差异:比如同时存在
MyStruct1(int)和MyStruct1(bool)两个非explicit构造函数,写法1传入true时可能因为重载解析优先级选择不符合预期的构造函数,和写法2显式指定构造类型的结果产生区别,但你给出的代码里只有一个单bool参数的构造函数,不存在这种歧义。
编译优化开启后,两种写法都会触发省略临时对象的优化操作,直接在左侧
myStruct1成员上完成值初始化,不会产生额外的临时对象构造开销,执行效率没有任何差异。
内容的提问来源于stack exchange,提问作者cyrusbehr
相关产品推荐
相关产品推荐

