9

我记得曾经有人告诉我,

“不需要auto内部基于范围的 for 循环。 如果我们要删除它,在语言中就不会模棱两可了。”

这是一个真实的说法吗?
以下代码是有效的 C++ 语法吗?

for (elem : range){...}  

我以为这已经是有效的语法,但是当我用 编译时
clang++ --std=c++1z,我看到了以下错误:

range-based for loop requires type for loop variable
 for (elem: range){

编译器仍然认为这是一个基于范围的 for 循环,那么为什么它不能也派生类型呢?

4

3 回答 3

10

这:

for (elem : range){...}  

语法当前无效,但有人提议使此语法有效,并且 gcc 5.2 支持该语法(现场查看):

#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 中实现的,期望提案 N3853: Range-Based For-Loops: The Next Generation将被接受,但被拒绝,更新版本N3994说:

这更新了 N3853(参见 [1]),它提出了语法“for (elem : range)”,增加了对属性的支持并回答了其他问题。此功能背后的原理请参见原始提案,此处不再赘述。

我们可以从EWG 问题 81中看到它被拒绝,我们也可以从厄巴纳会议纪要中看到这一点。尽管该提案存在许多问题,但我相信 STL 在提案的问答部分提出了一组令人信服的论点,我对该提案被拒绝感到失望。

于 2015-09-22T00:05:55.040 回答
4

语法需要 range-for 语句的类型,即使它是auto. for (elem : range) {...}是语法错误,所以从技术上讲,是的,这是真的,语言可以声明这相当于for (auto elem : range) {...}.

但是,这至少存在两个主要问题:

第一个是for (T elem : range)不需要T使用auto. 如果编译器看到for (elem,它还没有任何方法知道是来自外部范围elem的 some还是新声明的变量。typedef这不是模棱两可的,但是编译器要正确处理它有点复杂。

第二个是你会得到默认应该是什么的问题。可以提出合理的论据auto。可以提出合理的论据auto &。可以提出合理的论据const auto &。当前的方法只是让程序员选择。合法的论点可能(我不完全确定)也可以为一些auto替换为decltype(auto).

于 2015-09-21T23:29:32.817 回答
2

这对ELL来说真的是一个问题……

这句话是用虚拟语气写成的,这意味着它在谈论纯粹的假设情况,而不是实际的语言规则。虚拟语气用于反事实情况。

于 2015-09-21T23:26:11.053 回答