在下面的代码片段中,return s给出了警告local variable 's' will be copied despite being returned by name [-Wreturn-std-move]。为什么会这样呢?
我使用此 lambda 函数的目标是获取输入字符串的所有权,然后在通过 RVO 或移动语义修改后返回它。我真的很想避免任何复制。
const auto to_upper = [](std::string&& s) {
std::transform(s.begin(), s.end(), s.begin(),
[](unsigned char c){ return std::toupper(c); }
);
return s;
};
Run Code Online (Sandbox Code Playgroud)
返回std::move(s)orstd::forward<std::string>(s)将解决问题,但我认为这是没有必要的,因为编译器可以省略复制构造函数的使用。另外,我认为我应该使用std::forward,但哪一个是正确的,为什么?
如果函数按值返回,并且返回的变量与返回类型具有相同的类型,则有一条规则允许局部变量(包括函数参数)在返回时隐式移动(而不是复制)。
\n该警告告诉您,在这种情况下不会发生这种隐式移动,因为s是引用,并且该规则不适用于引用。
\n\n我想我应该使用 std::forward
\n
不,您应该使用std::move,因为您的参数不是转发引用。仅当是模板参数(或)T &&时才被视为转发引用,在调用时会推导出该参数。Tauto
看来 C++20 中的规则已更改,右值引用现在也可以隐式移动。从C++20开始,std::move这里可以去掉。
这受以下因素管辖:
\n\n\n\n
[class.copy.elision](C++20)3隐式可移动实体是具有自动存储持续时间的变量,它可以是非易失性对象,也可以是对非易失性对象类型的右值引用。\n在以下复制初始化上下文中,在尝试移动操作之前首先考虑移动操作复制操作:
\n(3.1) \xe2\x80\x94 如果 return ([stmt.return]) 或 co_\xc2\xadreturn ([stmt.return.coroutine]) 语句中的表达式是一个(可能带括号的)id 表达式,它命名了在最里面的封闭函数或 lambda 表达式的主体或参数声明子句中声明的隐式可移动实体,或者...
\n
C++20 之前的措辞有所不同,它只允许“自动对象”(而不是引用)。
\n| 归档时间: |
|
| 查看次数: |
1183 次 |
| 最近记录: |