我有这个功能:

fstream open_user_file() const
{
    ...
}

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

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

===============>>#1 票数:9 已采纳

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

返回具有自动存储的局部变量时,与声明的函数返回类型的类型相同,然后进行两阶段过程:

fstream open_user_file() const
{
    fstream f;

    /*...*/

    return f;
}
  1. 首先执行对副本的构造函数的选择,就好像该对象由rvalue指定一样。

  2. 如果第一个重载决策失败或未执行,或者所选构造函数的第一个参数的类型不是对象类型的rvalue引用(可能是cv-qualified),则再次执行重载决策,将对象视为左值。

这意味着如果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中,它们是。

===============>>#2 票数:3

实现可以省略由return语句产生的复制操作,即使复制构造函数具有副作用。 在这种情况下,您可能只需要明确移动。

fstream open_user_file() const
{
    fstream f;

    /*...*/

    return std::move(f);
}

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

...

这就是它说复制构造函数必须可访问的地方:

当满足或将满足复制操作的省略标准时 ,除了源对象是函数参数这一事实,并且要复制的对象由左值指定, 重载决策选择复制的构造函数是首先执行 ,好像对象是由右值指定的。 如果重载决策失败,或者所选构造函数的第一个参数的类型不是对象类型的rvalue引用(可能是cv-qualified),则再次执行重载决策,将对象视为左值。 [注意: 无论是否发生复制省略,都必须执行此两阶段重载决策。 如果未执行elision,它将确定要调用的构造函数,并且即使调用被省略,也必须可以访问所选的构造函数。

  ask by qdii translate from so

未解决问题?本站智能推荐:

1回复

该函数返回的RVO和rvalue如何工作?

为了理解编译器如何选择类的构造函数,我编写了以下代码: 根据Effective Modern C ++的第25项,由于返回值优化,编译器将w视为rvalue引用。 所以我期望Widget w(make_widget())调用移动构造函数。 但事实并非如此。 此外,它只打印
3回复

实现移动构造函数如何影响返回值优化?

请考虑以下代码段: 它用g++和clang++编译好,输出就是 在这种情况下,似乎RVO开始了。 请注意,没有调用移动构造函数。 但是,如果将从上面的代码中删除该未使用的移动构造函数,并且代码段变为: clang++和g++拒绝编译它,因为类A的copy-cons
2回复

返回向量,是在这里应用RVO还是move构造函数?

我有一个类,它具有一个std :: vector数据成员。 然后,我有一个简单的get成员函数,该函数仅按值返回数据成员。 当我调用以下C ++时: 此x86产生: 我期望要么应用返回值优化(RVO),要么使用std::vector move构造函数。 但是,我无法从
1回复

为什么Visual Studio在这种情况下不执行返回值优化(RVO)

我正在回答一个问题并建议为大型类型返回按值,因为我相信编译器会执行返回值优化(RVO) 。 但后来有人向我指出Visual Studio 2013没有在我的代码上执行RVO。 我在这里发现了一个关于Visual Studio无法执行RVO的问题,但在这种情况下,结论似乎是,如果真的很重要
2回复

如何返回本地对象的成员

请考虑以下代码: 在复制椭圆/移动语义方面实现getBigData()的最佳方法是什么? 在此实现中,似乎不允许编译器移动bigData 。 我测试了以下功能: 您能解释这些实现的结果,并显示返回本地对象成员的最有效方法。
1回复

返回锁定时C ++ 11移动

在“C ++ Concurrency in Action”一书中阅读以下方法 我无法理解为什么返回时head_lock是std :: move-ed。 我对移动用法和RVO的观念和直觉与C ++ 11 rvalues中共享的观点相匹配, 并且移动了语义混淆(return语句) 但
1回复

为什么c ++在返回本地std :: stringstream时不使用RVO?

我已经阅读了很多关于rvalue和在C ++中返回局部变量的信息> = 11.据我所知,“只是按值返回,不要使用move / forward而不添加&&方法签名,编译器会优化它适合你“。 好的,我希望它发生: 我很好 错误。 我不明白,为什么它会尝试
3回复

如何返回fstream(C ++ 0x)

我想我会直接进入它并从代码开始: 基本上,我需要返回一个流。 当然你不能复制一个ofstream,所以我在类测试中摆弄代码,然后我按照你的预期编译和工作(在gcc 4.5上)。 但我感觉不好这只是因为我的编译器在“auto os = test()”上做了“返回值优化”(RTO)。
1回复

实现fstream移动的C ++ 0x库

在找到如何返回fstream(C ++ 0x)的答案后,我现在想知道是否有一个当前的c ++ 0x库为fstream实现移动(甚至交换)(因为gcc(27.9)没有) 。 我更喜欢它是否也是免费的。 或者还有其他方式通过值从函数返回到fstream吗? 我已经尝试编译libcxx,
3回复

为什么fstream方法返回对“ * this”的引用?

我最近开始用C ++进行编码,但是我用C编写了很长时间。因此,我正在阅读fstream类中的方法,并且我发现可能是一个过程(不返回任何内容)的每个方法都将返回一个引用。到调用其方法的对象。 (例如,fstream&fstream :: read(char_type * __s,streamsi