基于范围的for循环无法检测遍历右值的技术原因是什么?
关于C++范围for循环处理右值容器的疑问
我遇到了如下C++代码:
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 }
静态分析工具标记这段代码存在错误,原因是转发引用e被std::move而非std::forward处理。
由于v的类型是右值引用,它必然绑定到prvalue或xvalue(客户端确认传入的是临时对象,或是希望fun将其视为临时对象)。我原本认为需要做两处修改:
- 将
for (auto&& e : v)改为for (auto&& e : std::move(v)); - 将
auto&&改为E&&(假设using E = std::decay_t<decltype(v)>::value_type;)。
但实际修改后并未达到预期效果:std::move对循环没有作用,e仍然从左值初始化;第二处修改直接导致编译错误。
查资料得知“无法检测是否在遍历临时对象(或其他右值)”,这印证了当前的语言限制。但我有个疑问:从基于范围for循环的语法展开来看,当范围表达式为右值时,把range-declaration = *__begin;改为range-declaration = std::move(*__begin);存在什么问题?
内容的提问来源于stack exchange,提问作者Enlico
相关产品推荐
相关产品推荐

