9

这是我想出的情况:

#include <iostream>
using namespace std;

struct test {
    test() { cout << "ctor" << endl; }

    test(const test&) = delete;
    test(test&&)      = delete;
};

auto f() -> test {
    return {};
    // return test{};
}

auto main() -> int {
    f();
}

这段代码用 clang 和 gcc 编译,但是当我改变return {}它时return test{}不再编译。这是为什么?它在两种情况下不应该是一样的吗?坦率地说,我不知道这是否有一个好的用例,但它让我感到惊讶,所以现在我想知道发生了什么。

4

2 回答 2

17

return {}使用空的初始化器列表来初始化返回值,使用默认构造函数。

return test{}使用默认构造函数创建一个临时对象,然后使用移动或复制构造函数使用它来初始化返回值。您已经删除了那些构造函数,因此无法完成。

在实践中,复制或移动将被省略,以便两者具有相同的效果 - 但第二个仍然需要一个可访问的构造函数,即使它没有实际使用。

于 2013-11-06T23:41:49.300 回答
0

As an extension of Mike's answer:

int main()
{
    // Error: Call to deleted move constructor (in C++98 the compiler would 
    // shout at the private copy constructor).
    // auto t = test{};

    // OK: Default constructor used
    test t2;
    test t3{};

    return 0;
}

Even though the move/copy is elided, the C++ standard requires visibility of these constructors.

于 2013-11-07T08:47:18.463 回答