自动和复制省略
Auto and copy elision
当使用 auto 并提交到特定类型时,复制省略的规则是什么? (参见:GotW - Almost always auto)。
根据我的理解,move/copy 构造函数需要可访问,即使它通常不被使用。但是下面的例子中 unique_ptr 和 fstream 有什么区别呢? (与 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++
。它目前在这方面不符合标准,即 iostream
s 虽然应该有,但还没有移动构造函数。它将在版本 5 中修复:
Runtime Library (libstdc++)
...
Full support for C++11, including the following new features:
...
movable and swappable iostream classes;
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
应该有一个移动构造函数,但您的实现还没有真正实现它。
当使用 auto 并提交到特定类型时,复制省略的规则是什么? (参见:GotW - Almost always auto)。
根据我的理解,move/copy 构造函数需要可访问,即使它通常不被使用。但是下面的例子中 unique_ptr 和 fstream 有什么区别呢? (与 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++
。它目前在这方面不符合标准,即 iostream
s 虽然应该有,但还没有移动构造函数。它将在版本 5 中修复:
Runtime Library (libstdc++)
...
Full support for C++11, including the following new features:
...
movable and swappable iostream classes;
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
应该有一个移动构造函数,但您的实现还没有真正实现它。