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
}