什么是`auto &&e` 在基于范围的 for 循环中做什么?

假设我在使用基于范围的循环编程时的当前规则说

Assuming my current rule when programming with range-based loops says

尽可能使用 for(auto const &e :...)for(auto &e:...) 而不是 for(自动 a: ...).

Use for(auto const &e :...) or for(auto &e:...) when possible over for(auto a: ...).

我以我自己的经验和这个问题为例.

I base this on my own experience and this question for example.

但是在阅读了新的 简洁的循环 我想知道,我不应该用 && 替换我的规则中的 & 吗?正如此处所写,这看起来像Meyers 的通用参考文献.

But after reading about the new terse for loops I wonder, should I not replace my & in my rule with &&? As written here this looks like the Meyers' Universal References.

所以,我问自己,我的新规则是否应该是

So, I ask myself, should my new rule either be

尽可能使用 for(auto const &&e :...)for(auto &&e:...) ...

Use for(auto const &&e :...) or for(auto &&e:...) when possible ...

或者这并不总是有效,因此应该是相当复杂的

or does that not always work and therefore should rather be the quite complicated one

检查 for(auto const &&e:...)for(auto &&e:...) 是否可行,然后考虑 for(auto const &e :...)for(auto &e:...),并且仅在需要时才使用引用.

Check if for(auto const &&e :...) or for(auto &&e:...) is possible, then consider for(auto const &e :...) or for(auto &e:...), and only when needed do not use references.

推荐答案

Howard Hinnant 此处.

When and if you should use auto&& in for loops has been explained very nicely by Howard Hinnant here.

这就留下了x

auto &&x = ...expr...

实际上是.并且像有函数模板定义一样处理

actually is. And it is handled as if there there were a function template definition

template <class U> void f(const U& u);

并且x的类型是按照与u[§7.1.6.4.(7)]相同的规则推导出来的.

and the type of x is deduced by the same rules as u [§7.1.6.4.(7)].

这意味着它不作为 RValue 参考处理,而是作为通用/转发参考"处理.--参考折叠规则"申请.

This means it is not handled as a RValue Reference, but as a "Universal/Forwarding Reference" -- the "Reference Collapsing Rules" apply.

这也适用于

const auto &&x = ...expr...

作为 §7.1.6.4.(7) 中的例子,至少对于 const auto &x.

as the example in §7.1.6.4.(7) states, at least for const auto &x.

但是,正如 PiotrS 在问题评论中所说,任何限定词都会使 URef-ness 无效:

But, as PiotrS says in the questions comments, any qualifiers nullifies the URef-ness:

不,因为template中的T都没有.void f(const T&&) 是转发引用,const auto&& 也不是.T&& 出现在参数声明中的事实并不意味着它是转发引用.只有没有像 constvolatile 这样的限定符的纯 T&& 是转发引用,这意味着它必须是 template;void f(T&&)auto&&,从不const T&&const auto&&代码>

no, because neither T in template<class T> void f(const T&&) is a forwarding reference, nor const auto&& is. The fact that T&& occurs in parameter declaration does not imply it is forwarding reference. Only pure T&& with no qualifiers like const or volatile is forwarding reference, meaning it has to be template<class T> void f(T&&) or auto&&, and never const T&& or const auto&&

相关文章