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

时间:2012-07-30 20:49:37

标签: c++ c++11

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

auto packet = DataPacket(); 

DataPacket packet;

5 个答案:

答案 0 :(得分:14)

首先回答有关auto的问题,生成的代码之间没有区别:

auto packet = DataPacket(); 

DataPacket packet = DataPacket();

但那不是你写的。

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

struct DataPacket { int i; };
{
  DataPacket packet = DataPacket();
  ++packet.i;  // OK
}
{
  DataPacket packet;
  ++packet.i;  // undefined behaviour
}

正如Xeo在下面的评论中指出的那样, 之间的差异

auto packet = DataPacket();

DataPacket packet{};

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

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

答案 1 :(得分:10)

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

答案 2 :(得分:4)

从编译器的角度来看,没有区别,除了你可以为变量指定父类型(如果你明确声明它)。从文体上来说,它会影响可读性(尽管它的正面或负面影响取决于人)。

编辑: 正如所指出的,第一个使用复制结构,而第二个使用默认构造函数。发现差异的迂腐解释here

答案 3 :(得分:1)

当您不知道某个表达式的类型时,auto关键字会很有用。您实质上是要求编译器在编译时确定变量的类型。就编译器而言,使用auto关键字和明确使用类型之间完全没有区别。

您还可以使用auto关键字来确定函数的返回类型,该函数的返回类型在编译时才会知道(与某些模板化函数一起发生)。请参阅此维基百科文章:Alternative function syntax

请注意,auto关键字不会为您提供RTTI。自动类型在编译时静态确定。

回到旧C天,auto关键字声明变量在堆栈上有“自动”存储,而不是存储在静态数据区域。

答案 4 :(得分:0)

在这种情况下,我建议使用第二种语法(不带“auto”关键字),因为它不那么详细。

这是auto有意义的一个例子:

map<int, pair<string, double>> M;
.... // Fill up M
// Without "auto":
map<int, pair<string, double> >::iterator it = M.find(5);
// With "auto":
auto autoit = M.find(5);
// Yet another example:
// Without auto:
for (pair<const int, pair<string, double>>& x: M) {
   // Do stuff
}
// With auto:
for (auto& x : M) {
   // Do stuff
}