C++ 不同对象的向量及其迭代器
我有两个不同对象的向量,我想使用它们的索引和迭代器 代码如下:C++ 不同对象的向量及其迭代器,c++,vector,indexing,iterator,C++,Vector,Indexing,Iterator,我有两个不同对象的向量,我想使用它们的索引和迭代器 代码如下: bool Database::Birth ( const string & name, const string & addr, const string & acc ) { SPerson personToAdd = SPerson ( name, addr ); SAccount accountToAdd = SAccount ( acc ); SP
bool Database::Birth ( const string & name, const string & addr,
const string & acc )
{
SPerson personToAdd = SPerson ( name, addr );
SAccount accountToAdd = SAccount ( acc );
SPiter = lower_bound ( SPeople.begin ( ), SPeople.end ( ), personToAdd );
/* this is the part I can't quite figure out */
size_t iterDistance = distance ( SPeople.begin ( ), SPiter );
SAiter = SAccounts.begin ( ) + iterDistance;
// this is where the segfault is happening
if ( ( SPiter -> s_name == name &&
SPiter -> s_addr == addr ) ||
SAiter -> s_account == acc ) return false;
SPeople.insert ( SPiter, personToAdd );
SAccounts.insert ( SAiter, accountToAdd );
return true;
}
我要做的应该是显而易见的——我想将一个对象(SPerson)插入到向量(SPeople)中的特定位置,并将另一个对象(SAccount)插入到同一索引下的向量(SAccounts)中。是否可以从迭代器中提取“索引”信息
我发现了几个类似的问题,但解决方案经常使用循环,我不需要(实际上因为性能原因而无法使用)。我绝对不能用lower_bound函数更改部件。您使用std::lower_bound的默认comp,即符号“在取消引用之前,您需要检查
Spitter
是否有效,因为lower_bound实际上可以返回SPeople.end()
如果查找值不小于任何元素。可能使用以下方法:
if ( SPiter != SPeople.end ( ) &&
(( SPiter -> s_name == name &&
SPiter -> s_addr == addr ) ||
SAiter -> s_account == acc )) return false;
此声明
size_t iterDistance = distance ( SPeople.begin ( ), SPiter );
if ( ( SPiter -> s_name == name &&
SPiter -> s_addr == addr ) ||
SAiter -> s_account == acc ) return false;
给你索引
但是要考虑到下一个if语句
size_t iterDistance = distance ( SPeople.begin ( ), SPiter );
if ( ( SPiter -> s_name == name &&
SPiter -> s_addr == addr ) ||
SAiter -> s_account == acc ) return false;
是错误的,因为如果找不到元素,则尝试访问超出其大小的向量。您需要再添加一个条件
if ( ( SPiter != SPeople.end ( ) && SPiter -> s_name == name &&
SPiter -> s_addr == addr ) ||
SAiter -> s_account == acc ) return false;
此外,如果一个人可以拥有多个帐户,那么仅检查上述条件是不够的。您应该使用相同的s_名称和s_addr迭代所有元素,以检查帐户是否已经存在
我认为您应该执行以下操作,而不是if语句
while ( SPiter != SPeople.end ( ) &&
SPiter -> s_name == name &&
SPiter -> s_addr == addr &&
SAiter -> s_account != acc )
{
++SPiter; ++SAiter;
}
if ( SPiter != SPeople.end ( ) && SPiter -> s_name == name && SPiter -> s_addr == addr )
{
return false;
}
SPeople.insert( SPiter, personToAdd );
SAccounts.insert( SAiter, accountToAdd );
return true;
您做得很对-从
SPeople.begin()
调用std::distance
会为您提供索引。当您使用此方法时,是否会看到问题?您需要在此处输入标识符Saiter here=SAccounts.begin()+iterInstance;
。除此之外,这应该可以工作。当std::distance
与RandomAccessIterator
参数一起使用时,它以恒定时间计算距离。这是std::vector
迭代器的情况。但是,您可以使用普通的-
减法运算符,而不是std::距离
…哇,我很惊讶我这么做是正确的。问题是我在我的终端中看到了很好的旧“分段错误”。我更深入地研究了这个问题,它来自我没有发布b/c的部分代码。我认为这无关紧要。我要更新这个问题。我认为更紧迫的编码/设计问题是名称的使用sSPIter
和SAIter
。它们似乎是在某个封闭类或命名空间范围中定义的变量。这是不好的,因为它会从任意的实现细节中泄漏信息,并且可能会使其他代码中关于这些变量值的假设无效。请改用局部变量。