RVO在C 11中启动所需的移动构造函数/分配



例如:

在接受答案中https://stackoverflow.com/a/14623480/1423254,

确实复制了Elision,RVO仍然可以在不移动的情况下工作构造函数?

是的,RVO仍然开始。实际上,编译器有望选择:RVO(如果可能的话(

在接受答案中https://stackoverflow.com/a/38043447/1423254,

在非保证复制责任规则下,这将创建一个临时的,然后从该临时性转移到函数的返回值中。那移动操作可能会被省略,但T仍然必须具有可访问的移动即使从未使用过构造函数。

关键是我认为rvo and quot" lvalue移动"(或如何打电话给他们(是2个完全独立的操作,但是我的同事告诉我,要使RVO开始,班级返回需要移动构造函数。因此,我检查了互联网,因此很明显,这些信息无法迅速找到...

no,如果可以访问复制构造函数。

在C 17之前并保证复制率,一个移动构造函数或复制构造函数必须可供代码合法。省略只是一种优化,不影响代码是否会编译。

也就是说,有一个两个步骤的过程:

  • 评估语句return <expr>;是合法的,在C 17之前,该语句需要(限制转换(,即复制构造函数或在存在临时的临时构造函数的情况下,请出现移动构造函数和可访问
  • 如果可能

考虑到这一点,让我们回顾一下引号:

复制Elision和RVO是否仍然可以在不移动构造函数的情况下为课程工作吗?

是的,RVO仍在开始。实际上,编译器有望选择:RVO(如果可能的话(

应该在法律的代码中理解。如果代码不编译,则问题是没有。

在非保证复制责任规则下,这将创建一个临时性,然后从该临时性转移到函数的返回值中。可以将这种移动操作浮出水面,但是即使从未使用过,T也必须具有可访问的移动构造函数。

这是一个缩写;试图考虑可能缺乏移动构造函数的句子,因此复制构造函数的后备只会弄清楚解释,而OP没有迹象表明存在这种情况。

简短答案:否。

当没有"移动构造函数"之类的东西时,

rvo也存在于C 11之前。在这种情况下,复制构造函数是唯一的要求。

"在非保证复制省权规则下。

自C 17以来,以下代码编译(保证零副本/移动(:

struct foo
{
    foo() = default;
    foo(const foo&) = delete;
    foo(foo&&) = delete;
};
foo get_foo() { return foo{}; }
int main()
{
    foo f{get_foo()};
}

最新更新