我在这里阅读了 std::for_each
的文档 http://en.cppreference.com/w/cpp/algorithm/for_each并看到返回值为 std::move(f)
为什么标准强制在返回值中 move 输入参数?无论如何,它不会默认 move 吗,因为输入参数是按值传递的?
当您编译以下代码时,这会引导我进行一些跟进
Something function(Something something) {
return something;
}
return 语句在我的系统上是最高优化级别(
-O3
) 的一个 Action ,为什么大多数编译器不省略这个返回值?局部值被省略,但函数参数没有..在这种情况下,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 的 move 语义规则的最新更改。 The original move proposal当按值函数参数出现在 return 子句上时,不会自动 move 。然而,在 C++11 过程的后期,该语言功能被添加了。
在添加语言功能之前,for_each
“被 move 了”。那时 return 语句上的 move 是必要的。但是在 C++11 发布时它变得没有必要了,尽管它是无害的。
LWG issue 2747针对 C++17 更正了这一点。
关于你的第一个后续问题,我不是编译器编写者,但我最好的猜测是:从函数参数中删除返回值目前是不合法的(我知道的很多),我猜为什么它不合法是因为没有人想出如何实现它,因此没有人有动力改变标准以使其合法。
第二次跟进:不,C++17 在这种情况下不强制省略。在这种情况下,规则与 C++11 相同,只是不再指定 for_each
的冗余 move 。
来自以下评论:
Why do you say it's not legal to elide the return from a function parameter?
我引用的是 N4660 ,也就是C++17,但是C++98/03/11/14里面也有类似的写法……备份,最近已经被保护了。参见 N4659相反(同样好):
15.8.3 复制/move 省略 [class.copy.elision]
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
这种语言特别禁止省略函数参数。
关于c++ - 为什么for_each通过move返回函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43163801/