我看到了
here以下的代码.描述说:
We can also capture as a forwarding reference using auto&&. That is,
auto&& will resolve to auto& for lvalue references, and auto&& for
rvalud references. Here is an example of capturing the output from a
range-based for loop over a temporary map.
我确实理解汽车和放大器的腐烂汽车与汽车如果引用的值是左值(所以在这种情况下没有衰减).我努力的方法是了解临时地图,基于循环的范围和移动的值如何协同工作.您是否愿意解释这些事情如何相互协作以及为什么可以从正在迭代的临时事件中移除.
#include <iostream>
#include <map>
std::map<std::string, int> get_map()
{
return {
{ "hello", 1 },
{ "world", 2 },
{ "it's", 3 },
{ "me", 4 },
};
}
int main() {
for (auto&& [ k, v ] : get_map())
std::cout << "k=" << k << " v=" << v << '\n';
}
最佳答案 auto&& amp;有两种不同的用途.在这个例子中,一个可见,一个隐藏.为了最大限度的冗长,你已经扩展到的循环:
{
auto&& __range = get_map(); // the temporary get_map() is bound to a reference, which
// extends its lifetime to the lifetime of the reference
// decltype(__range) is std::map<std::string, int>&&
auto __begin = __range.begin();
auto __end = __range.end(); // potential different type from __begin since C++17
for (; __begin != __end; ++__begin) {
auto&& __elem = *__begin; // this is your structured binding declaration
// *__begin is an lvalue, so decltype(__elem) is
// std::pair<std::string const, int> const&
// the actual destructuring here
std::string const& k = std::get<0>(__elem);
int const& v = std::get<1>(__elem);
// now your body
std::cout << "k=" << k << " v=" << v << '\n';
}
}
因此:
why it’s ok to move from a temporary that is being iterated.
此代码中的任何地方都没有发生任何变化.地图是在__range中构建的,这就是你要迭代的内容.它超出了最后一个支架的范围.
请注意:
I do understand the decaying of
auto&&
toauto&
if the value referred to is an lvalue
不太正确.首先,它不被称为“衰变” – 例如,当你将一个数组传递给一个函数时,衰变就会发生 – 它会衰变成一个指针.此外,汽车&&不会崩溃成汽车&.只是,如果初始化程序是左值,则自动&&和汽车&表现方式相同.如果初始化程序是右值,则auto&&工作(并产生右值参考)而汽车&无法编译.