我在这里看到了下面的代码。描述说:
我们还可以使用 auto&& 捕获作为转发参考。也就是说,对于左值引用,auto&& 将解析为 auto&;对于右值引用,auto&& 将解析为 auto&&。以下是在临时地图上捕获基于范围的 for 循环的输出的示例。
auto&&如果引用的值是左值,我确实理解 to 的auto&衰减(因此在这种情况下没有衰减)。我所努力的是理解临时地图、基于范围的 for 循环和移动的值如何一起工作。您愿意解释一下这些东西如何相互作用,以及为什么可以从正在迭代的临时对象中移动。
#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';
}
Run Code Online (Sandbox Code Playgroud)
auto&&在这个例子中有两种不同的用途,一种是可见的,一种是隐藏的。为了尽可能详细,您的循环扩展到:
{
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';
}
}
Run Code Online (Sandbox Code Playgroud)
因此:
为什么可以从正在迭代的临时对象中移动。
这段代码中的任何地方都没有发生任何移动。是map在 中就地构建的__range,这就是您要迭代的内容。它超出了最后一个大括号的范围。
请注意:
如果引用的值是左值,我确实理解
auto&&to的衰减auto&
不太正确。首先,它不被称为“衰减”——衰减是指当你将一个数组传递给一个函数时发生的情况——它衰减成一个指针。而且,auto&&不会崩溃成auto&. 只是,如果初始化器是左值,auto&&并且auto&行为方式相同。如果初始值设定项是右值,auto&&则可以工作(并生成右值引用),但auto&无法编译。
| 归档时间: |
|
| 查看次数: |
1232 次 |
| 最近记录: |