不同对象的矢量和使用它们的迭代器

时间:2014-03-22 12:04:12

标签: 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 );

    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)插入到同一索引下的向量(SAccount)中。是否有可能提取"索引"来自迭代器的信息?

我发现了几个类似的问题,但解决方案经常使用循环,我不需要(并且由于性能而实际上无法使用)。我绝对无法使用lower_bound函数更改该部分。

3 个答案:

答案 0 :(得分:0)

您对 std :: lower_bound 使用默认comp,这是符号“<”。所以在你的情况下必须正确地重载。 std :: distance 为您提供下限的索引,但似乎您需要lower_bound + 1.

答案 1 :(得分:0)

在取消引用之前,您需要检查SPiter是否有效,因为如果查找值不小于任何元素,lower_bound实际上可以返回SPeople.end()。可能使用类似的东西:

if ( SPiter != SPeople.end ( ) &&
     (( SPiter -> s_name == name &&
     SPiter -> s_addr == addr ) ||
     SAiter -> s_account == acc )) return false;

答案 2 :(得分:0)

本声明

size_t iterDistance = distance ( SPeople.begin ( ), SPiter );

为您提供索引。

但考虑到下一个if语句

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_name和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;