为什么 for_each return 是靠着手运作的

Why does for_each return function by move

我在此处阅读 std::for_each 的文档 http://en.cppreference.com/w/cpp/algorithm/for_each 并看到 return 值是 std::move(f)

为什么标准强制移动 return 值中的输入参数?无论如何,它不会默认移动吗,因为输入参数是按值传递的?


当您编译以下代码时,这会引导我进行一些跟进

Something function(Something something) {
    return something;
} 
  1. return语句是我系统上优化级别最高的一个动作(-O3),为什么大多数编译器不省略这个return值?局部值被省略但函数参数没有..

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

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

这是由于 C++11 的移动语义规则的最新更改所致。当按值函数参数出现在 return 子句上时,The original move proposal 不会自动移动。然而,在 C++11 过程的后期,添加了该语言功能。

在添加语言功能之前,for_each "was moved"。那时 return 语句的移动是必要的。但它变得不必要了,尽管在 C++11 发布时是无害的。

LWG issue 2747 针对 C++17 更正了此问题。

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

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

来自以下评论:

Why do you say it's not legal to elide the return from a function parameter?

我引用的是 N4660, which is C++17, but there is similar wording in C++98/03/11/14 ... backup, it has recently been protected. See N4659(同样好):

15.8.3 Copy/move 省略 [class.copy.elision]

  1. When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, ...

    • in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function parameter or a variable introduced by the exception-declaration of a handler (18.3)) with the same type (ignoring cv-qualification) as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function call’s return object

此语言明确禁止省略函数参数。