基于范围的 for 循环与 decltype(auto)

Range-based for loop with decltype(auto)

在使用基于范围的情况下,是否存在 decltype(auto)auto 更好的选择(可能使用 &&& 或 cv 限定符)循环?换句话说,你会写下面的代码吗?

for (decltype(auto) item : range) {
    // ...
}

decltype(auto) 当输入迭代器returns 时生成不同类型的值。 auto&& 创建一个对临时文件的右值引用,而 decltype(auto) 创建一个本地副本(在 C++17 中它只是命名临时文件,因为保证省略更改)。

这没什么区别。在 C++11/14 中,它在 decltype(auto) 情况下需要一个移动构造函数(在实践中不调用,但需要),但在 C++17 中则不需要。在 auto&& 中,移动构造函数未被调用且不需要。

另一个区别是 decltype(item) 的类型,它是一个总是带有 auto&& 的引用,但在临时返回输入 iteraror 的情况下 decltype(item) 是一个值类型。

就是这样。实际上,我认为没有理由 decltype(auto) 而不是 auto&&

顺便说一句,auto& 强制非右值,const auto& 强制非可变,auto 强制复制。有理由使用 auto&& 而不是那些,但这超出了这个问题的范围。 decltype(auto) 最接近 auto&&,所以我比较了这两个。

如前所述here

decltype(auto) is primarily useful for deducing the return type of forwarding functions and similar wrappers

[...]

although it can be used to declare local variables, doing that is probably just an antipattern since a local variable’s reference-ness should not depend on the initialization expression

也就是说,在基于范围的 for 循环中使用 转发引用 是可行的方法。
如前所述 here:

It is safe, and in fact, preferable in generic code, to use deduction to forwarding reference

我建议 this 关于 SO 的问题,以获取有关在基于范围的 for 循环中使用通用引用的更多详细信息。