返回不可移动的不可复制对象时,ctor {}和{}之间的差异

时间:2013-11-06 23:36:28

标签: c++ c++11

以下是我提出的情况:

#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{}时,它不再编译。这是为什么?在这两种情况下,它的功能是否都不一样? 坦率地说,我不知道是否有一个很好的用例,但它让我感到意外,所以现在我想知道发生了什么。

2 个答案:

答案 0 :(得分:17)

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

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

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

答案 1 :(得分:0)

作为Mike答案的延伸:

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;
}

即使删除了移动/复制,C ++标准也要求可见这些构造函数。

相关问题