首页 > 解决方案 > C++ 中的对象初始化语法( T obj = {...} vs T obj{...} )

问题描述

T obj = {…}两种形式的初始化有什么区别T obj{…}
我最初认为这是将临时对象复制到我们的新对象中的T obj = {…}简写。T obj = T{…}这虽然不执行复制构造函数(复制省略),但需要它的存在和访问它。但是当我通过将构造函数设为私有来阻止此特定类中的复制构造函数访问时,没有错误。
这意味着不涉及复制机制。那么'='符号的作用是什么?
我已经提到了以下问题,但由于没有解释而感到不满意:
C++11 统一初始化是否可以替代旧式语法?

编辑:int arr[]{…}在类似的说明中,和之间有区别int arr[] = {…}吗?我问这个看看我是否可以带出统一初始化和列表初始化之间的对比。

标签: c++constructorinitializationlist-initializationuniform-initialization

解决方案


这些具有几乎完全相同的效果:

  • T x = { 1, 2, 3 };
  • T x { 1, 2, 3 };

从技术上讲,具有的版本=称为复制列表初始化,另一个版本是直接列表初始化,但这两种形式的行为由列表初始化行为指定。

区别在于:

  • 如果copy-list-initialization选择了explicit构造函数,则代码格式错误。
  • 如果Tauto,那么:
    • 复制列表初始化推断std::initializer_list<Type_of_element>
    • direct-list-initialization只允许列表中的单个元素,并推导出Type_of_element.

更多信息:为什么标准区分直接列表初始化和复制列表初始化?


如果T是数组类型,则上述内容仍然适用;由于数组列表初始化始终是聚合初始化,因此永远不会选择构造函数,因此两个版本在所有情况下都是相同的。


T obj = T{...}(不包括auto)与 完全一样,因为 C++17 ,T obj{...}直接列表初始化. obj在 C++17 之前,有一个临时的直接列表初始化,然后是obj从临时的复制初始化。


推荐阅读