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的部分代码。我认为这无关紧要。我要更新这个问题。我认为更紧迫的编码/设计问题是名称的使用s
SPIter
SAIter
。它们似乎是在某个封闭类或命名空间范围中定义的变量。这是不好的,因为它会从任意的实现细节中泄漏信息,并且可能会使其他代码中关于这些变量值的假设无效。请改用局部变量。