自动和复制省略

Auto and copy elision

当使用 auto 并提交到特定类型时,复制省略的规则是什么? (参见:GotW - Almost always auto)。

根据我的理解,move/copy 构造函数需要可访问,即使它通常不被使用。但是下面的例子中 unique_ptrfstream 有什么区别呢? (与 noexcept 有关?)

#include <memory>
#include <fstream>

int main()
{
    auto f = std::fstream{"foo.bar"};
    auto i = std::unique_ptr<int>{new int};

    return 0;
}


// main.cc:6:10: error: call to implicitly-deleted copy constructor of 'std::basic_fstream<char>'
//    auto f = std::fstream{"foo.bar"};
//         ^   ~~~~~~~~~~~~~~~~~~~~

我猜你使用 libstdc++。它目前在这方面不符合标准,即 iostreams 虽然应该有,但还没有移动构造函数。它将在版本 5 中修复:

Runtime Library (libstdc++)

...

Full support for C++11, including the following new features:

...

movable and swappable iostream classes;

来自 version 5 changelog

auto推导和复制省略与此无关;您的代码与:

std::fstream f = std::fstream{"foo.bar"};
std::unique_ptr<int> i = std::unique_ptr<int>{new int};

在这两种情况下,这都指定了一个 copy/move 操作,这意味着如果移动构造函数可用则使用移动构造函数,否则使用复制构造函数。

如您所说,即使 copy/move 在实践中会被省略,但标准要求代码在没有省略的情况下符合标准要求。 (这样正确的代码就不会神秘地编译,然后根据优化决定等编译失败)

显然,C++11 指定 fstream 应该有一个移动构造函数,但您的实现还没有真正实现它。