相关疑难解决方法(0)

迭代器失效的规则

在STL容器类(Vector,Dequeue,list,map,multimap,set,multiset)上操作时,Iterator失效的常用规则是什么?是否有可能对C++ STL程序员在处理容器及其迭代器时必须注意的一些一般规则/指南进行分类和总结?

c++ iterator stl invalidation

5
推荐指数
1
解决办法
2181
查看次数

std :: multimap获得两个范围

我正在使用C++ std::multimap,我必须循环两个不同的键.有没有一种有效的方法来做到这一点,除了创建两个范围并单独循环这些范围?

这就是我现在这样做的方式:

std::pair<std::multimap<String, Object*>::iterator,std::multimap<String, Object*>::iterator> range;
std::pair<std::multimap<String, Object*>::iterator,std::multimap<String, Object*>::iterator> range2;

// get the range of String key
range = multimap.equal_range(key1);
range2 = multimap.equal_range(key2);

for (std::multimap<String, Object*>::iterator it = range.first; it != range.second; ++it)
{
    ...
}
for (std::multimap<String, Object*>::iterator it2 = range2.first; it2 != range2.second; ++it2)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

c++ iterator std range multimap

5
推荐指数
1
解决办法
900
查看次数

为什么在达到容量后在向量中完成插入时,C++不会处理迭代器?

我编写这个小代码只是为了看看迭代器是如何实际失效的,并且在达到容量之后没有指向向量的更改位置.

这里矢量和容量的大小最初都是5.之后我在向量中插入了一些其他元素,并没有重新初始化我的迭代器指向myvector.begin().49maximum size of vector is : 1073741823再次打印向量元素之后,这会导致输出中的垃圾值.

我的问题是为什么myvector.begin()在将所有元素复制到新位置后,C++不再使点迭代器成为有效的?
这也可能导致一些难以调试的行为.我知道一种安全的工作方式是在使用之前始终重新初始化迭代器.

  #include<iostream>
  #include<vector>
  #include<stdio.h>

  using namespace std;

  int main()
  {
    vector<int> myvector;
    vector<int>::iterator it;
    int myarray[]= {100,200,300,400};
    myvector.insert(it,500);
    it=myvector.begin();
    myvector.insert(it,myarray,myarray+4);
    it=myvector.begin();
    for(;it!=myvector.end();++it)
    cout <<*it<<endl;
    cout <<"size of vector is :" << myvector.size() <<"\n"; 
    cout <<"capacity of vector is : " << myvector.capacity()<<"\n";  
    cout <<"maximum size of vector is : " << myvector.max_size()<<"\n"; 
    myvector.push_back(600);
    for(;it!=myvector.end();++it)
    cout <<*it<<endl;
  }
  Output of program :-
  100
  200 …
Run Code Online (Sandbox Code Playgroud)

c++ iterator vector

5
推荐指数
1
解决办法
344
查看次数

用C++做两次事的成语

两次做某事有一个共同的习惯用法,如下列情况?

    for ( int i = 0; i < num_pairs; i++ ) {
        cards.push_back( Card(i) );
        cards.push_back( Card(i) );
    }
Run Code Online (Sandbox Code Playgroud)

我有一种感觉,比引入一个从0到1计数的新循环变量有一个更清晰的方法,特别是因为除了计数之外它没有被使用.

    for ( int i = 0; i < num_pairs; i++ )
        for ( int j = 0; j < 2; j++ )
            cards.push_back( Card(i) );
Run Code Online (Sandbox Code Playgroud)

(Card只是我编写的一些课程,与问题无关.)

c++ idioms

5
推荐指数
3
解决办法
538
查看次数

指向 std::vector 结构体的指针

struct Struct_t {
    int Value1;
    int Value2;
};

vector<Struct_t> Struct;
Struct.resize(10, Struct_t());

for (int i = 0; i < 10; ++i)
{    
    Struct[i].Value1 = (i + 10) * 3;
    Struct[i].Value2 = (i + 5) * 2;
}
Run Code Online (Sandbox Code Playgroud)

如何创建指向 Struct[i] 的指针?

我想要做的基本上是这样的,但我相信这可以做得更好:

int value = 6;
Struct_t temp = Struct[value], *s;
s = &temp;

s->Value1 = 42;
s->Value2 = 6;
Run Code Online (Sandbox Code Playgroud)

主要目标是,我可以使用 1 行/函数轻松创建指向 Struct[n] 的指针。

c++ arrays struct pointers vector

5
推荐指数
1
解决办法
3935
查看次数

通过属性值从向量中删除对象的 unique_ptr

我有一个具有这三个功能的 Holder 对象

unique_ptr<Object> Holder::remove(string objName){
    std::vector<unique_ptr<Object>>::iterator object = 
            find_if(objects.begin(), objects.end(),
            [&](unique_ptr<Object> & obj){ return obj->name() == objName;}
     );
    objects.erase(std::remove(objects.begin(), objects.end(), *object));
    return std::move(*object);
}

vector<unique_ptr<Object>> const& Holder::getContent() const {
    return this->objects;
}

void Holder::add(unique_ptr<Object> objPtr) {
    this->objects.push_back(move(objPtr));
}
Run Code Online (Sandbox Code Playgroud)

我写了一个 CPPunit 测试如下:

void HolderTest::removeObject() {
    Holder holder("bag");
    unique_ptr<Object> ringPtr(new Object("a"));
    holder.add(move(ringPtr));

    unique_ptr<Object> swordPtr(new Object("b"));
    holder.add(move(swordPtr));

    holder.remove("a");
    vector<unique_ptr<Object>> const& objects = holder.getContent();
    CPPUNIT_ASSERT(objects.size() == 1);
}
Run Code Online (Sandbox Code Playgroud)

这个测试毫无问题地通过,但对我来说很奇怪的是,如果我添加以下行:

const std::string name = objects[0].get()->name();
CPPUNIT_ASSERT_EQUALS("b", name);
Run Code Online (Sandbox Code Playgroud)

然后测试在没有任何消息的情况下崩溃。我在另一个测试中编写了这一行而没有调用 remove 并且它没有任何问题。如果我将向量大小的值更改为 2 或 0 CPPUNIT_ASSERT(objects.size() …

c++ smart-pointers vector unique-ptr c++11

5
推荐指数
1
解决办法
6802
查看次数

使用迭代器删除元素,而不知道向量

我有一个情况.我已经使用模板化函数完成了我的任务之一.对于这个函数,我通过引用传递迭代器.现在,我必须从向量中删除一些元素.如何仅使用迭代器来完成此操作?Pl找到相应的代码:

template <class BidirectionalIterator, class Iterator> bool

SomeFunc( BidirectionalIterator& first, BidirectionalIterator& last, Iterator anotherVecBegin )
{
    while((first+1) != last)
    {
        if(some_condition)
            // delete (first); HOW?
        else if(some_other_condition)
            // delete (first + 1); HOW?
    }

    // add something to another vector using anotherVecBegin

    return true;
}
Run Code Online (Sandbox Code Playgroud)

有许多已经问过的问题,但它们都有一个上下文的向量.所以myVec.erase(*first)很容易..

我也知道它不是一个非常好的方式,我通过引用传递迭代器.但我遵循简单的规则:在预期某些事情发生变化时使用引用或避免重复复制.我的方案符合第一个条件.

那么如何删除?

c++ templates iterator vector c++11

5
推荐指数
1
解决办法
610
查看次数

迭代器如何在向量重新分配后更新

这是我正在查看的代码片段:

vector<int> iv = {1,2,3,4,5,6,7,8,9,10};
auto iter = iv.begin(), mid = iv.begin() + iv.size()/2;
for(int count = 100; count; --count ) {
    iter = iv.insert(iter, - 1);
    cout << "capacity = " << iv.capacity() << "*mid = " << *mid << endl;

}
Run Code Online (Sandbox Code Playgroud)

根据迭代器失效规则:
vector:插入点之前的所有迭代器和引用都不受影响,除非新容器大小大于先前容量(在这种情况下所有迭代器和引用都无效)[23.2.4.3/1] 迭代器失效规则

我明白,因为我在每次插入操作中重新分配"iter"的值,或许我能够保持它的有效性(如果我错了,请纠正我).但是,迭代器"mid"在这种情况下仍然有效,即使我没有在循环中篡改它,也当向量的容量发生变化时.

那么,"mid"在重新分配后如何能够自我更新?

要知道mid是否完全改变,我将代码中的第4行更改为:

iv.insert(iter, -1); // Did not assign it back to iter.
Run Code Online (Sandbox Code Playgroud)

打印在中间取消引用该值的结果表明该更改,并且可能也表明它已失效.(如果我错了,请再次纠正我).

c++ iterator stl c++11

5
推荐指数
1
解决办法
353
查看次数

将向量迭代器转换为指针

我有一个矢量std :: vector.我想迭代向量找到匹配,如果找到想要返回指向元素的指针,如下所示:

const int * findint(std::vector <int> &v, int a)
{
        std::vector<int>::const_iterator i1,i2;
        i1 = v.begin();
        i2 = v.end();
        for(;i1 != i2;++i1) {
                if(a== *i1) {
                        return(i1);
                }
        }
        return(0);
}
Run Code Online (Sandbox Code Playgroud)

这是使用GNU g ++ 2.95.3编译器进行编译和工作正常但不能使用GNU g ++ 4.9.2进行编译并给出以下错误:

error: cannot convert 'std::vector<GenFld>::const_iterator {aka __gnu_cxx::__normal_iterator<const int*, std::vector<int> >}' to 'const int*' in return
     [exec]     return(i1);
Run Code Online (Sandbox Code Playgroud)

需要帮忙.

c++ pointers iterator vector c++11

5
推荐指数
1
解决办法
1万
查看次数

C++ 中的 Bron Kerbosch 算法

我一直在练习我的 C++ 算法知识,并陷入了标准 BK 实现。该算法输出了太多的派系,我似乎不明白为什么。我将图表示为邻接列表:

vector< list<int> > adjacency_list;
Run Code Online (Sandbox Code Playgroud)

我的 BK 函数如下所示:

void graph::BronKerbosch(vector<int> R, vector<int> P, vector<int> X){

  if (P.empty() && X.empty()){
    result_cliques.insert(R);
  }

  for (int node : P){

    vector<int> intersection = {}, intersectionX = {};

    //N(P)
    for (int nodeP : adjacency_list[node]){
      for (int node2 : P){
        if (nodeP == node2){
          intersection.push_back(nodeP);
        }   
      }

      //N(X)
      for (int node3 : X){
        if (nodeP == node3){
          intersectionX.push_back(nodeP);
        }
      }
    }

    R.push_back(node);
    BronKerbosch(R,intersection,intersectionX);
    P.erase(remove(P.begin(),P.end(),node),P.end());
    X.push_back(node);    

  }
}
Run Code Online (Sandbox Code Playgroud)

我用以下方式称呼它:

void graph::run_BronKerbosch(){

  vector<int> R,P,X; …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm

5
推荐指数
1
解决办法
2978
查看次数