在使用auto时初始化结构会导致VS 2013中的副本

initializing struct while using auto causes a copy in VS 2013

本文关键字:VS 2013 副本 auto 结构 初始化      更新时间:2023-10-16

在以下代码中,创建nested对象的行只使用gcc打印"构造函数",而不使用VS 2013打印:

#include <iostream>
using namespace std;
struct test {
    test()            { cout << "constructor" << endl; }
    test(const test&) { cout << "copy constructor" << endl; }
    test(test&&)      { cout << "move constructor" << endl; }
    ~test()           { cout << "destructor" << endl; }
};
struct nested {
    test t;
//    nested() {}
};
auto main() -> int {
    // prints "constructor", "copy constructor" and "destructor"
    auto n = nested{};
    cout << endl;
    return 0;
}

输出:

constructor
copy constructor
destructor
destructor

所以我想这里发生的是一个临时对象被复制到n中。没有编译器生成的移动构造函数,所以这就是它不是移动的原因。

我想知道这是一个错误还是一种可以接受的行为?为什么添加默认构造函数会阻止复制?

问题不是auto;以下将显示相同:

nested n = nested{};

临时用{}直接初始化,然后用它复制初始化n,因为test是一个类类型(在本例中,具有用户定义的构造函数)。

允许直接初始化最终目标(n),但没有义务,因此两者都是合法的。

本标准8.5和8.5.1中的大量(实际上是大量)详细信息。

这是MSVC执行复制省略的失败(我想这与brace-init构造函数有关)。这两种方式都是完全合法的。