在下面的例子中,i有函数范围.但似乎我不能i在第二个for循环使用.为什么不起作用for (i : v1),但for (int i : v1)有效?
#include<iostream>
#include<string>
#include<vector>
int main()
{
std::vector<int> v1;
int i;
while(std::cin>>i)
{
v1.push_back(i);
}
for(i : v1) //for (int i:v1) works
std::cout<<i<<"\t";
cout<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*ner 39
这是一个语法问题,基于范围的for循环需要声明一个命名变量,即它需要一个类型说明符(cf,例如,cppreference.com):
for(range_declaration:range_expression)loop_statement
range_declaration - 命名变量的声明,其类型是range_expression表示的序列元素的类型,或对该类型的引用.经常使用auto说明符进行自动类型推导
其实我不知道为什么你的问题被贬低了; 我觉得你的假设很好; 只是C++语法决定以另一种方式定义它.
Die*_*ühl 34
基于范围的for是专门用于替换类似于以下的循环(这是一个有点简单的情况;基于范围for,尤其是C++ 17版本,比示例更通用):
for (auto it = range.begin(), end = range.end(); it != end; ++it) {
use(*it);
}
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,不会使用不同位置的值,而是使用位置本身的元素:
因此,基于范围的设计者for决定绝对必须支持引用.同时,它旨在对基于范围的使用相当简单的重写规则for.在标准中编纂的规则是:
for (<range-decl>: <range>) { <body> }
Run Code Online (Sandbox Code Playgroud)
相当于
{
auto&& range = <range>; // keep the range alive!
auto it = begin(range); // actually, reality is bit more complicated
auto end = end(range); // actually, reality is a bit more complicated
for (; it != end; ++it) {
<range-decl> = *it; // this is the rewrite causing your issue
<body>
}
}
Run Code Online (Sandbox Code Playgroud)
特别是,其含义是,<range-decl>是一个声明,而不是仅仅命名的变量.这种要求的原因通常是在前面使用的实体:是参考.但是,引用不能反弹.但是,在循环的每次迭代中,可以使用新的引用.
原则上,如果<range-decl>不是声明而是左值,则重写规则可以使用赋值.那会产生一些奇怪的行为:
for (T const& x: range)和之间会有区别T const& x = 0; for (x: range):前者有效,后者有误.T& x = get_reference(); for (x: range) {...}),则循环会自动将范围中的所有值分配给位于某处的对象.通常,对象要么位于堆栈上,要么位于源范围内(当变量被声明为引用时).根据变量的声明方式,仅允许初始化比支持初始化或赋值更合理.查看提案的修订历史(N2930和前任)并未引起讨论,但我含糊地回忆起这一点已经讨论过了.
| 归档时间: |
|
| 查看次数: |
2073 次 |
| 最近记录: |