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

cat*_*dle 9 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();
}
Run Code Online (Sandbox Code Playgroud)

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

Mik*_*our 17

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

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

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

  • 注意:从C ++ 17开始,这两个版本都是合法的,在返回表达式和结果对象之间不再存在概念上的临时性 (2认同)