8

我正在阅读std::for_each这里的文档http://en.cppreference.com/w/cpp/algorithm/for_each并看到返回值是std::move(f)

为什么标准强制在返回值中移动输入参数?由于输入参数是按值传递的,所以默认情况下不会移动它吗?


当您编译以下代码时,这导致我进行了一些后续操作

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),但我不完全了解哪些情况符合强制省略的条件。

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

4

1 回答 1

12

这是由于 C++11 的移动语义规则的最新变化。 当返回子句中出现按值函数参数时,最初的移动提议不会自动移动。然而,在 C++11 进程的后期,该语言特性被添加了。

在添加语言功能之前,for_each“已移动”。那时,有必要在退货声明上采取行动。但是在 C++11 发布时它变得不必要了,尽管它已经无害了。

LWG 问题 2747已针对 C++17 纠正了此问题。

至于您的第一个后续问题,我不是编译器编写者,但我最好的猜测是:目前从函数参数中省略返回是不合法的(我知道的就这么多),我猜为什么会这样不合法是没有人想出如何实施它,因此没有人有动力改变标准以使其合法。

第二次跟进:不,C++17 在这种情况下不强制省略。在这种情况下,规则与 C++11 的规则相同,除了for_each不再指定冗余移动的事实。

从下面的评论:

为什么你说从函数参数中省略返回是不合法的?

我引用的是N4660,它是 C++17,但在 C++98/03/11/14 ... 备份中有类似的措辞,它最近受到了保护。请参阅N4659(同样好):

15.8.3 复制/移动省略 [class.copy.elision]

  1. 当满足某些条件时,允许实现省略类对象的复制/移动构造,...

    • return具有类返回类型的函数的语句中,当表达式是非易失性自动对象的名称(除了函数参数或由处理程序的异常声明(18.3)引入的变量之外具有相同type(忽略cv-qualification)作为函数返回类型,可以通过将自动对象直接构造到函数调用的返回对象中来省略复制/移动操作

这种语言特别不允许从函数参数中省略。

于 2017-04-02T02:12:01.880 回答