返回一个fstream
Returning an fstream
我有这个函数:
fstream open_user_file() const
{
...
}
但是我的编译器抱怨fstream
复制构造函数被隐式删除。既然编译器执行RVO,为什么选择复制构造函数而不是移动构造函数?
否则,最好的方法是什么?
当前接受的答案是错误的。
当返回具有自动存储的局部变量时,其类型与函数声明的返回类型相同,则有两个阶段的过程:
fstream open_user_file() const
{
fstream f;
/*...*/
return f;
}
首先执行副本构造函数的选择,就好像对象是由右值指定的一样。
如果第一个重载解析失败或没有执行,或者如果所选构造函数的第一个参数的类型不是对对象类型的右值引用(可能是cv限定的),则会再次执行重载解析,将对象视为左值。
这意味着,如果f
是可移动构造的,那么对于返回f
,这将是优选的(并且可能被忽略)。否则,如果f
是可复制构造的,则将为返回f
而完成(并且可能被忽略)。否则,无法从此函数返回f
,并且会导致编译时错误。
唯一的情况是:
return std::move(f);
当实现出现错误时应该会有所帮助。在一致性实现中,fstream
是可移动构造的,并且:
return f;
将是最佳的。如果f
不可移动构造,则:
return std::move(f);
不会有助于实现一致性。如果在一致的实现中进行编码,将产生令人讨厌的效果,因为它将抑制RVO。
gcc 4.8没有实现可移动流(并且流是不可复制的)。这就是你问题的根源。在C++98、C++03和gcc 4.8中,流不可从函数返回。在C++11中,它们是。
即使复制构造函数有副作用,实现也可能省略由返回语句产生的复制操作。在这种情况下,您可能只需要明确移动即可。
fstream open_user_file() const
{
fstream f;
/*...*/
return std::move(f);
}
当满足某些条件时,允许实现省略类的复制/移动构造对象,即使为复制/移动操作选择的构造函数和/或对象的析构函数有副作用。
这就是它所说的复制构造函数必须可访问的地方:
当满足省略复制操作的标准时或者除了源对象是一个函数参数,要复制的对象由左值指定,重载解析为选择复制首先执行的构造函数,就好像对象是由右值指定的一样。如果过载解析失败,或者如果所选构造函数的第一个参数的类型不是对的右值引用对象的类型(可能是cv限定的),再次执行重载解析,将对象视为左值。[注意:无论复制省略是否会发生它确定在不执行省略时要调用的构造函数,以及所选的构造函数必须是可访问的,即使取消了调用
- fstream库,试图创建一个变量名为(c++)的文件
- 使用 fstream 在空格分隔文件中查看下一项(不仅仅是一个字符)的方法
- 我无法使用 c++(代码块)中的 fstream 将文件内容复制到另一个。如何运行该文件?
- 可视化了一个关于c++文件I/O和fstream的问题
- 有效而干净的方法来编写一个ofstream/fstream对象,以用标头编写表
- 做一个popen(),将文件*指针放入fstream中,pclose()呢?
- C++fstream在.txt中搜索一个结构
- Fstream不会保存文件中的最后一个单词,也不会从文件中读取
- 为什么 fstream::open() 需要一个 C 样式的字符串
- 从文件读取,而另一个进程正在使用 std::fstream 写入该文件
- fstream指向一个特定的路径(到桌面ex.)
- 使用C++fstream类在另一个目录中打开一个文件
- fstream初始化为一个类
- 为什么我得到一个错误说eof不是fstream的类类型
- Fstream排序-不需要一个空格字符
- c++ Fstream只打印一个单词
- 通过CLI从c#向c++传递一个fstream(或等价)
- 返回一个fstream
- 在二进制整数 (C++) 中读取后,fstream 是否移动到下一个位置
- 打开一个fstream进行读写(二进制)