首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回fstream

返回fstream
EN

Stack Overflow用户
提问于 2014-04-19 23:05:02
回答 2查看 994关注 0票数 4

我的职能是:

代码语言:javascript
复制
fstream open_user_file() const
{
    ...
}

但是我的编译器抱怨fstream复制构造函数被隐式删除。假设编译器执行RVO,为什么选择复制构造函数而不是移动构造函数?

否则,最好的办法是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-21 03:44:50

目前所接受的答案是错误的。

当返回具有自动存储的局部变量时,其类型与函数的声明返回类型相同,则有两个阶段处理:

代码语言:javascript
复制
fstream open_user_file() const
{
    fstream f;

    /*...*/

    return f;
}
  1. 对副本的构造函数的选择首先被执行,就好像对象是由rvalue指定的一样。
  2. 如果第一个重载解析失败或没有执行,或者所选构造函数的第一个参数的类型不是对对象类型(可能是cv限定的)的rvalue引用,则将再次执行重载解析,将对象视为lvalue。

这意味着如果f是可移动的,这将是返回f的首选(可能是省略的)。否则,如果f是可复制的,则将执行(并可能被省略)以返回f。否则,无法从此函数返回f,将导致编译时错误。

唯一的情况是:

代码语言:javascript
复制
return std::move(f);

应该帮助是当实现是错误的。在符合规范的实现中,fstream是可移动的,并且:

代码语言:javascript
复制
return f;

会是最优的。如果f不可移动,那么:

代码语言:javascript
复制
return std::move(f);

不会对符合标准的实现有所帮助。如果在符合标准的实现中进行编码,则会产生悲观的效果,因为它会抑制RVO。

gcc 4.8没有实现可移动的溪流(而且流是不可复制的)。这就是你问题的根源。在C++98、C++03和gcc 4.8中,流不能从函数返回。在C++11,他们是。

票数 10
EN

Stack Overflow用户

发布于 2014-04-19 23:18:14

即使复制构造函数有副作用,实现也可能省略返回语句导致的复制操作。在这种情况下,您可能只需显式地移动。

代码语言:javascript
复制
fstream open_user_file() const
{
    fstream f;

    /*...*/

    return std::move(f);
}

当满足某些条件时,即使为复制/移动操作选择的构造函数和/或对象的析构函数具有副作用,也允许实现省略类对象的复制/移动构造。

..。

它说,复制构造函数必须是可访问的:

当复制操作的省略条件满足或将满足以下事实时,除非源对象是函数参数,而且要复制的对象由lvalue指定,则首先执行重载解析以选择副本的构造函数,就好像该对象是由rvalue指定的一样。如果重载解析失败,或者所选构造函数的第一个参数的类型不是对象类型的rvalue引用(可能是cv限定的),则再次执行重载解析,将对象视为lvalue。[注意:无论复制是否会发生,这个两阶段重载解析都必须执行。如果不执行省略,它将确定要调用的构造函数,并且即使调用被省略,所选的构造函数也必须是可访问的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23176583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档