C++ 默认初始化与从默认构造值复制初始化

C++ 默认初始化与从默认构造值复制初始化,c++,c++11,C++,C++11,让thing成为默认的可构造和可移动的可构造类型。考虑下面两个初始化: thing t1; // (1) auto t2 = thing{}; // (2) (1) 默认构造t1 (2) default构造一个类型为thing的临时对象,并将其移动到t2中 在何种情况下,入住(2)将被取消? 在现代风格C++初始化中,类型通常不出现或出现在右边。例如: auto copy = vec; // Type doesn'

thing
成为默认的可构造和可移动的可构造类型。考虑下面两个初始化:

thing t1;          // (1)
auto t2 = thing{}; // (2)
  • (1) 默认构造
    t1

  • (2) default构造一个类型为
    thing
    的临时对象,并将其移动到
    t2

在何种情况下,入住(2)将被取消?

在现代风格C++初始化中,类型通常不出现或出现在右边。例如:

auto copy = vec;                              // Type doesn't appear

auto p_derived = std::make_unique<derived>(); // Type appears naturally on the right

// Putting the type on the right here makes it explicit that the upcast is intended
auto p_base = std::unique_ptr<base>{ std::make_unique<derived>() };
auto copy=vec;//类型不显示
自动p_派生=标准::使_唯一();//类型自然出现在右侧
//将类型放在这里的右边可以清楚地表明向上投射是有意的
auto p_base=std::unique_ptr{std::make_unique()};
使用(2)将与这些样式一致,而使用(1)则不一致

此外,如果将(1)与长typename一起使用,则变量名将显示在最右侧。使用(2)时,无论typename有多长,变量名都是相同的appparent


这是否意味着为了一致性,(2)比(1)更可取?

哪个更可取是一个意见问题。我不想加入,这不是我的目的

每一个支持C++11的现代编译器都将省略该动作,除非您将显式编译器标志传递给从不省略的对象

在C++17中,没有移动到elide;
thing{}
是一个prvalue,在C++17中,prvalue不是对象,而是创建对象的指令(可以实例化匿名临时对象,但在本例中不是)

autox=
prvalue
语句导致prvalue指令用于构造
x

在什么情况下,移入(2)将被省略

当编译器选择删除时。现代编译器上几乎总是这样。但是,在C++11(或C++14)中没有保证的拷贝省略

使用(2)将与这些样式一致,而使用(1)则不一致

这是否意味着为了一致性,(2)比(1)更可取

为了一致性,一致性几乎没有什么好处

理解为什么示例中的类型位于右侧,以及为什么(这意味着)
auto
存在是很有用的。类型位于右侧,因为模板实例化需要它。类型仍然必须位于左侧,才能具有声明的语法。该类型也是右侧表达式的返回类型,因此引入了
auto
,以允许从该表达式中进行推断。这是有利的,因为我们避免了类型的脆弱重复

(1) 没有重复,因此在引入
auto
时没有重复数据消除的优势。没有右手表达,也没有必要引入右手表达。(2) 有不必要的额外样板,并且增加了类型可移动的要求

此外,如果将(1)与长typename一起使用,则变量名将显示在最右侧。使用(2)时,无论typename有多长,变量名都是相同的appparent

在我看来,这是一个软弱的论点。无论如何,您应该避免使用不必要的长字体名,但如果您使用的是一个,您可以简单地将它们放在单独的行中:

thing_with_extra_long_type_name_for_some_reason<omg_it_doesnt_end>
  t1;
thing\u与\u extra\u long\u类型\u name\u出于某种原因
t1;

无论如何与复制elsiion无关。