c++ - 为什么for_each通过move返回函数

标签 c++ c++11 move c++17 copy-elision

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

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


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

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

  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 的 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]

  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

这种语言特别禁止省略函数参数。

关于c++ - 为什么for_each通过move返回函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43163801/

相关文章:

Linux 查找子目录中的所有文件并 move 它们

c++ - LNK2019错误未解析的外部符号

c++ - 在 C++ 中一般比较继承层次结构中的对象

c++ - 如何在 Linux mint 17.1 (KDE) 中安装代码块

c++ - 初始化对象数组中的 vector 大小

vector - 函数如何将值附加到向量并返回该值?

c++ - arduino 网络客户端随机卡住

c++ - 在 C++ 中自动引用 vector

c++ - ISO 8601 时间戳 C++

c++ - 编译器调用复制运算符而不是 move 运算符