实际上这些是两个相关的问题。
我知道C ++ 11中有一种新语法可用于基于范围的for
循环形式:
//v is some container
for (auto &i: v){
// Do something with i
}
第一个问题:我怎样才能推断出我在这个循环中的迭代? (假设我想在位置j处填充值为j的向量)。
第二个问题:我想知道是否还有其他方法来编写表格
的循环for (int i=0; i<100; i++) { ... }
我发现这种编写方式有点麻烦,我经常这样做,我希望有一个更简洁的语法。 一些事情:
for(i in [0..99]){ ... }
会很棒。
对于这两个问题,我希望避免使用其他库。
答案 0 :(得分:21)
第一个回答:你不是。你为了一个简单的目的使用了一个简单的结构;如果你有更复杂的需求,你会需要更复杂的东西。
第二个答案:你可以创建一个产生连续整数值的迭代器类型,以及一个&#34;容器&#34;提供一系列类型的类型。除非你有充分的理由亲自去做,否则Boost有such a thing:
#include <boost/range/irange.hpp>
for (int i : boost::irange(0,100)) {
// i goes from 0 to 99 inclusive
}
答案 1 :(得分:15)
答案 2 :(得分:11)
对于第一个问题,答案很简单:如果你需要迭代计数,不要使用抽象迭代计数的句法结构。只需使用普通的for
循环,而不是基于范围的循环。
对于第二个问题,我不认为目前标准库中有任何内容,但您可以使用boost::irange
:
for (int i : boost::irange(0, 100))
答案 3 :(得分:4)
对于第二个问题 - 如果Boost太重,您可以随时使用此库:
for(auto i : range(10, 15)) { cout << i << '\n'; }
将打印10 11 12 13 14
for(auto i : range(20, 30, 2)) { cout << i << '\n'; }
将打印20 22 24 26 28
也支持双打和其他数字类型。
它有其他pythonic迭代工具,并且只是标题。
答案 4 :(得分:3)
您可以使用Boost.Range执行这两项操作:http://boost.org/libs/range
boost::adaptors::indexed
:元素值&amp;索引boost::irange
:整数范围为了简洁起见(并且由于boost::irange
已经被孤立地证明了,因此可以提高一些东西),这里有一个示例代码,展示了这些功能在一起工作:
// boost::adaptors::indexed
// http://www.boost.org/doc/libs/master/libs/range/doc/html/range/reference/adaptors/reference/indexed.html
#include <boost/range/adaptor/indexed.hpp>
// boost::irange
// http://www.boost.org/doc/libs/master/libs/range/doc/html/range/reference/ranges/irange.html
#include <boost/range/irange.hpp>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> input{11, 22, 33, 44, 55};
std::cout << "boost::adaptors::indexed" << '\n';
for (const auto & element : input | boost::adaptors::indexed())
{
std::cout << "Value = " << element.value()
<< " Index = " << element.index()
<< '\n';
}
endl(std::cout);
std::cout << "boost::irange" << '\n';
for (const auto & element : boost::irange(0, 5) | boost::adaptors::indexed(100))
{
std::cout << "Value = " << element.value()
<< " Index = " << element.index()
<< '\n';
}
return 0;
}
示例输出:
boost::adaptors::indexed
Value = 11 Index = 0
Value = 22 Index = 1
Value = 33 Index = 2
Value = 44 Index = 3
Value = 55 Index = 4
boost::irange
Value = 0 Index = 100
Value = 1 Index = 101
Value = 2 Index = 102
Value = 3 Index = 103
Value = 4 Index = 104
答案 5 :(得分:1)
如果v
是一个向量(或任何std
个连续容器),那么
for(auto& x : v ) {
size_t i = &x-v.data();
x = i;
}
将第i个条目设置为值i
。
计数的输出迭代器相当容易编写。 Boost有一个名为irange
的容易生成的范围。
提取容器的索引相对容易。我编写了一个名为indexes
的函数,它可以获取一个容器或一系列整数,并在相关范围内生成随机输出迭代器。
这会给你:
for (size_t i : indexes(v) ) {
v[i] = i;
}
Boost中可能存在等效的容器到索引范围函数。
如果你需要两者,并且你不想做这项工作,你可以写一个拉链。
for( auto z : zip( v, indexes(v) ) ) {
auto& x = std::get<0>(z);
size_t i = std::get<1>(z);
x = i;
}
其中zip
采用两个或更多可迭代范围(或容器),并生成元素iterator_traits<It>::reference
元组的范围视图。
这是Boost zip迭代器:http://www.boost.org/doc/libs/1_41_0/libs/iterator/doc/zip_iterator.html - 可能存在一个Boost拉链范围处理类似上述zip
函数的语法。
答案 6 :(得分:1)
对于第二个问题:
还有另一种方法,但我不使用或推荐。但是,为了快速设置测试,您可以写:
如果您不想使用库,只需提供您可以编写的范围的上限即可:
for (auto i:vector<bool>(10)) {
cout << "x";
}
这将创建一个大小为10的布尔向量,带有未初始化的值。使用i
循环使用这些单位化值(所以不使用i
)它将打印10次&#34; x&#34;。
答案 7 :(得分:0)
对于第二个问题,如果您使用的是最新的Visual Studio版本,请键入&#39; if&#39;然后 Tab , Tab 和 Tab 来填写初始值,升级等等。