我记得有人曾经告诉过我,
“基于范围的for循环中不需要
auto
。它会 如果我们要删除它,不会在语言中含糊不清。“
这是真实的陈述吗? 以下代码是否有效的C ++语法?
for (elem : range){...}
我原以为这已经是有效的语法了,但是当我用as编译时
clang++ --std=c++1z
,我看到以下错误:
range-based for loop requires type for loop variable
for (elem: range){
编译器仍然将其识别为基于范围的for循环,那么为什么它也不能导出类型呢?
答案 0 :(得分:10)
在:
for (elem : range){...}
语法目前无效,但有人建议使用此有效语法,gcc 5.2( see it live )支持该语法:
#include <vector>
int main()
{
std::vector<int> v ;
for( elem : v )
{
}
}
如果我们在C ++ 14模式下尝试这个,它会说:
警告:基于范围的for循环,只有类型说明符可用 使用-std = c ++ 1z或-std = gnu ++ 1z
所以这显然可行,并已在gcc中实现。看起来此功能已在gcc 6.0中删除。
据我所知,这是在gcc中实现的,期望proposal N3853: Range-Based For-Loops: The Next Generation会被接受,但被拒绝且更新版本N3994说:
这更新了N3853(见[1]),它提出了语法&#34; for(elem: 范围)&#34;,通过添加对属性的支持和回答额外的 的问题。请参阅原始提案,了解背后的理由 此功能,此处不再重复。
我们可以看到它已被EWG issue 81拒绝,我们也可以从Urbana meeting minutes看到这一点。尽管该提案存在许多问题,但我认为STL在提案的问答部分提出了令人信服的一系列论点,我对该提案遭到拒绝感到失望。
答案 1 :(得分:4)
语法需要range-for语句的类型,即使它是auto
。 for (elem : range) {...}
是语法错误,所以从技术上讲,是的,这是真的,语言可以声明这相当于for (auto elem : range) {...}
。
但至少存在两个主要问题:
首先,for (T elem : range)
不需要T
才能使用auto
。如果编译器看到for (elem
,它将无法知道elem
是来自外部作用域的某个typedef
,还是新声明的变量。它并不含糊,但编译器正确处理有点复杂。
第二个是你接下来应该得到默认值的问题。可以为auto
进行合法的论证。可以为auto &
进行合法的论证。可以为const auto &
进行合法的论证。目前的方法只是让程序员选择。对auto
替换为decltype(auto)
的一些人来说,可能(我不完全确定)也可以进行合法的论证。
答案 2 :(得分:2)
这对ELL来说真的是个问题......
这句话是用虚拟语气写的,这意味着它是在谈论纯粹假设的情况,而不是实际的语言规则。虚拟语气用于反事实情况。