这个问题的原因是我见过这样的代码:
auto fun(std::vector<Foo>&& v) {
std::vector<Bar> w;
for (auto&& e : v /* not an rvalue, but keep reading */) {
w.push_back(std::move(e));
}
// do stuff with w
}
其被静态分析工具标记为错误,因为转发参考X1 M0 N1 X是X1 M1 N1 XD而不是X1 M2 N1 XD。
另一方面,v
肯定会绑定到纯右值或x值(客户端知道或者希望fun
作为临时变量),因为它的类型是一个右值引用。是的,我看到函数体没有以任何方式声明v
不能在for
循环之后使用,但那只会让我觉得我应该改变
for (auto&& e : v)
到for (auto&& e : std::move(v))
,- 和
auto&&
到E&&
,假设沿着using E = std::decay_t<decltype(v)>::value_type;
的线。
据我所知,第一点并没有达到我所期望的效果,事实上,std::move
似乎对for
没有影响,反过来,e
一直从左值初始化(至少在operator[]
返回v
类型的引用的常见情况下是这样),而第二个点只会导致编译错误。
作为附加参考,注解¹
从this answer读取(参考范围-for
循环)
无法检测是否正在对临时值(或其他右值)进行迭代
这似乎证明了我做不到。
但是,看看range-for
循环是如何去糖的,当 * range-expression
* 是右值时,将range-declaration` = *__begin;`更改为
range-declaration= std::move(*__begin);
会有什么错误?
1条答案
按热度按时间vtwuwzda1#
容器是右值并不意味着它所包含的内容是
该决定应由
std::move_iterator
*std::forward_like
move_iterator
,右值begin
/end
的重载在当前标准中不起作用,通常调用。加上no standard container support them either。