当使用auto并提交到特定类型时,复制省略的规则究竟是什么? (见:GotW - Almost always auto)。
根据我的理解,移动/复制构造函数必须是可访问的,即使它通常不被使用。但是,下面的示例中 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"};
// ^ ~~~~~~~~~~~~~~~~~~~~
答案 0 :(得分:3)
我猜你使用libstdc++
。在这方面,它目前不符合标准,即iostream
s还没有移动构造函数,尽管它们应该具有。它将在版本5中修复:
来自 version 5 changelog 的运行时库(libstdc ++)
...
完全支持C ++ 11,包括以下新功能:
...
可移动和可交换的iostream类;
答案 1 :(得分:2)
auto
扣除和复制省略与此无关;你的代码与:
std::fstream f = std::fstream{"foo.bar"};
std::unique_ptr<int> i = std::unique_ptr<int>{new int};
在这两种情况下,这都指定了一个复制/移动操作,这意味着使用移动构造函数(如果有),否则使用复制构造函数。
正如你所说,即使复制/移动在实践中被省略,标准要求代码符合标准要求而不需要省略。 (这样,正确的代码不会神秘地编译,然后根据优化决策等而无法编译。)
显然,C ++ 11指定fstream
应该有一个移动构造函数,但是你的实现还没有实现。