C++ c++;迭代器循环与索引循环
我知道这个问题很愚蠢,但我想澄清一下 假设我有一个字符串向量C++ c++;迭代器循环与索引循环,c++,iterator,boost-tokenizer,C++,Iterator,Boost Tokenizer,我知道这个问题很愚蠢,但我想澄清一下 假设我有一个字符串向量 vector<int> vnTemp; // suppose this vector has {1,2,3,4,5} vector<int>::iterator vn_it; //Now, I want to print out only 1 to 4. for(int i=0; i<4; ++i) cout << vnTemp[i] << endl; 这是原始代码,当
vector<int> vnTemp; // suppose this vector has {1,2,3,4,5}
vector<int>::iterator vn_it;
//Now, I want to print out only 1 to 4.
for(int i=0; i<4; ++i)
cout << vnTemp[i] << endl;
这是原始代码,当我在for循环中尝试说tokens.end()-1
时会发生错误
有什么办法可以解决这个问题吗?
很抱歉出现歧义。
boost::tokenizer
仅提供前向迭代器;这意味着您不能从标记器迭代器中减去。如果希望循环避免处理最后一个令牌,则必须在处理当前使用的令牌之前“向前看”。像这样的
tokenizer tokens(strLine, sep); //strLine is some string line
tok_it = tokens.begin();
if(tok_it!=tokens.end())
{
++tok_it;
for(auto last_tok = tokens.begin(); tok_it != tokens.end(); ++tok_it){
// Process last_tok here
. . .
last_tok = tok_it;
}
}
编辑:
另一种方法是将令牌复制到具有更灵活迭代器的容器中:
std::vector<std::string> resultingTokens(tokens.begin(), tokens.end());
for(auto tok=resultingTokens.begin(); tok!=resultingTokens.end()-1; ++tok)
{
// whatever
}
std::vector resultingTokens(tokens.begin()、tokens.end());
for(auto-tok=resultingTokens.begin();tok!=resultingTokens.end()-1;++tok)
{
//随便
}
这应该行得通。迭代器实现运算符-
。此外,迭代器不仅仅是指针。例如,std::list
将其元素保存在非连续内存中。我想说您的问题是人为造成的。现实世界中的问题通常涉及整个容器,或者其他一些可以用迭代器很好地编写的选择(如remove\u if
或find
),迭代器确实比索引更适合谈论集合。前向迭代器支持增量,双向迭代器支持递增和递减,而随机访问迭代器既支持递增和递减,也支持附加的算法,如begin()+4
。。。vector使用随机访问迭代器,所以您可以选择。我相信boost::tokenizer
默认为std::string::const_iterator
boost::token_iterator
是一个前向迭代器,这就是问题的原因。哦,我明白了。在这种情况下,是否可以设置迭代的步长?这个答案基本上是正确的,但需要进行一些清理:+1
仍然无法在前向迭代器上工作-只能使用增量运算符:++
。另外,更正确的说法是,充其量boost::tokenizer
将生成前向迭代器。例如,如果底层容器是一个流,boost::tokenizer
将生成稍微有限的输入迭代器。没错。谢谢@MichaelWhat如果我想设置步长?说2?我可以这样写吗?++(++tok_____________________________________________<代码>++(++tok____it)
应该可以工作,但它会使代码变得复杂。而且它对令牌的数量很敏感(您确实需要检查每次增量后是否命中end()
)。如果您打算使用这些奇怪的步骤和边界对令牌进行迭代,只需将令牌复制到其他容器(如deque
)中,您就可以使用随机访问迭代器-代码可能会更干净。您的第一种方法是增加begin()返回的迭代器
然后将其与end()
进行比较,后者在没有令牌时会有未定义的行为-使用控制for
循环的if
语句可以轻松修复。
tokenizer tokens(strLine, sep); //strLine is some string line
tok_it = tokens.begin();
if(tok_it!=tokens.end())
{
++tok_it;
for(auto last_tok = tokens.begin(); tok_it != tokens.end(); ++tok_it){
// Process last_tok here
. . .
last_tok = tok_it;
}
}
std::vector<std::string> resultingTokens(tokens.begin(), tokens.end());
for(auto tok=resultingTokens.begin(); tok!=resultingTokens.end()-1; ++tok)
{
// whatever
}