2017-04-02 105 views
6

我读了std::for_each这里http://en.cppreference.com/w/cpp/algorithm/for_each的文档,发现返回值是std::move(f)为什么for_each的通过移动

为什么标准中强制执行的返回值移动输入参数恢复功能?无论如何,它会不会被默认移动,因为输入参数是按值传递的?


这使我一对夫妇followups,当你编译下面的代码

Something function(Something something) { 
    return something; 
} 
  1. return语句是我的系统上的举动最高优化级别(-O3)为什么大多数编译器不会退出这个返回值?本地值被省略,但函数参数不是..

  2. 在这种情况下,C++ 17是否强制使用?我阅读了提案(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0135r0.html),但我并不完全了解哪些情况符合强制性的要求。

我已经在我的Mac和g++ 5.4在Ubuntu 16.04试过这对Apple LLVM version 8.0.0 (clang-800.0.42.1)

回答

11

这是由于C++ 11移动语义规则的最新改变造成的。当返回子句中出现by-value函数参数时,The original move proposal不会自动移动。然而,在C++ 11过程的后期,该语言功能被添加了。

在添加语言功能之前,for_each“已被移动”。那时,回归声明的举动是必要的。但是在C++ 11出货时它变得没有必要,尽管无害。

LWG issue 2747对C++ 17进行了更正。关于你的第一个后续问题,我不是一个编译器的作家,但我最好的猜测是:从函数参数(我知道的那些)中退出是不合法的,而且我猜测为什么它不合法是因为没有人知道如何实施它,因此没有人有动机改变标准使之合法。

第二次后续:否,在这种情况下,C++ 17不强制执行省略。在这种情况下,规则保持与C++ 11相同,除了不再指定从for_each的冗余移动。

从下面的评论:

你为什么说这是不合法的从的Elid函数参数的回报?

我引用N4660,这是C++ 17,但有类似的措辞在C++ 98/01/11/14-备份,它最近被保护。见N4659代替(一样好):

15.8.3复制/移动省音[class.copy。省音]

  1. 当满足一定的条件,实现允许省略类对象的复制/移动建设,在......在函数中return声明

    • 当类型返回类型为时,表达式是非易失性自动对象的名称(除了函数参数或由异常声明引入的变量之外的一个) ER(18.3))与相同类型(忽略CV-资格)作为函数返回类型时,复制/移动操作可以通过直接构建自动对象到函数调用的返回对象被省略

该语言明确禁止从函数参数中删除。

+0

你为什么说退出函数参数是不合法的?我查看它的函数参数值的方式与局部变量相同,只是构造和破坏的顺序未指定。 – Curious

+0

@Curious:用C++ 17的引用更新来解决这个问题。 –

+0

最后一件事。为什么该提案不允许从函数论点中删除?我只是想了解决定背后的原因。 – Curious