为什么 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;
}
return语句是我系统上优化级别最高的一个动作(-O3
),为什么大多数编译器不省略这个return值?局部值被省略但函数参数没有..
在这种情况下,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]
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
此语言明确禁止省略函数参数。
我在此处阅读 std::for_each
的文档 http://en.cppreference.com/w/cpp/algorithm/for_each 并看到 return 值是 std::move(f)
为什么标准强制移动 return 值中的输入参数?无论如何,它不会默认移动吗,因为输入参数是按值传递的?
当您编译以下代码时,这会引导我进行一些跟进
Something function(Something something) {
return something;
}
return语句是我系统上优化级别最高的一个动作(
-O3
),为什么大多数编译器不省略这个return值?局部值被省略但函数参数没有..在这种情况下,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]
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
此语言明确禁止省略函数参数。