使用auto声明变量和使用type-name之间有什么区别?

Dri*_*ise 5 c++ c++11

例如,我有一些课DataPacket.有什么区别:

auto packet = DataPacket(); 
Run Code Online (Sandbox Code Playgroud)

DataPacket packet;
Run Code Online (Sandbox Code Playgroud)

Jon*_*ely 14

要回答关于auto第一个问题,生成的代码之间没有区别:

auto packet = DataPacket(); 
Run Code Online (Sandbox Code Playgroud)

DataPacket packet = DataPacket();
Run Code Online (Sandbox Code Playgroud)

但这不是你写的.

在原始问题中,第一个创建一个值初始化的临时,然后packet从中复制初始化.这需要一个可访问的,非显式的复制或移动构造函数,要求类型可以是默认构造的,并确保packet初始化(假设复制/移动构造函数没有错误.)第二个默认初始化packet,只需要type可以是默认构造的,但如果对象具有普通的默认构造函数,则会使对象保持未初始化状态,例如:

struct DataPacket { int i; };
{
  DataPacket packet = DataPacket();
  ++packet.i;  // OK
}
{
  DataPacket packet;
  ++packet.i;  // undefined behaviour
}
Run Code Online (Sandbox Code Playgroud)

正如Xeo在下面的评论中指出的那样,这些之间的差异较小:

auto packet = DataPacket();

DataPacket packet{};
Run Code Online (Sandbox Code Playgroud)

因为第二个也确保了值初始化,所以在这种情况下,前者需要一个可访问的,非显式的复制或移动构造函数.

在所有需要可访问的复制/移动构造函数的情况下,如果未删除副本(或移动),则生成的代码将因复制/移动而不同.但实际上,所有现代编译器都会省略它,因此生成的代码将是相同的.

  • @FredOverflow,不,如果它有一个被调用的默认构造函数,请参见[dcl.init.list]/3"如果初始化列表没有元素且T是具有默认构造函数的类类型,则该对象是值初始化的". (2认同)

Ben*_*igt 10

第一个是复制初始化,如果没有可访问的复制或移动构造函数,则会失败.

  • @ildjarn:是的,但标准仍然使用术语"复制初始化". (3认同)
  • 此外,标记为"explicit"的复制/移动构造函数将失败(我不确定"可访问"是否指的是那个). (2认同)