传递指针向量并擦除重复项

passing a vector of pointers and erasing duplicates

本文关键字:擦除 指针 向量      更新时间:2023-10-16

我正试图擦除一个指针向量,该向量是我按值传递给某个函数的。我传递值的原因是,我计划在对函数的多次调用中删除这些值。因此,如果我通过指针/引用,我就无法实现这一点。

首先,上面的说法正确吗?

以下是一些示例代码:

vector<Boson*>* BosonMaker::remove_duplicates(vector<Boson*>* boson_candidates, vector<Particle*> child_candidates){
  vector<Particle*> used_leptons.clear();
  // This needs deleting at some point
  m_unduplicated_bosons = new vector<Boson*>();
  for(int i_b = 0; boson_candidates->size(); i_b++){
    vector<Particle*>::iterator child1_finder = find(used_leptons.begin(), used_leptons.end(), boson_candidates->at(i_b)->Child1());
    //Search pointer will reach end of collection if child isn't in the used_leptons vector
    if (child1_finder == used_leptons.end()) {
      vector<Particle*>::iterator child2_finder = find(used_leptons.begin(), used_leptons.end(), boson_candidates->at(i_b)->Child2());
      if (child2_finder == used_leptons.end()) {
        used_leptons.push_back(boson_candidates->at(i_b)->Child1());
        used_leptons.push_back(boson_candidates->at(i_b)->Child2());
        // And add the boson to the vector of final bosons
        unduplicated_bosons->push_back(boson_candidates->at(i_b));
      }
    }
  }
  // Now make a vector of unused leptons
  for (int i_l = 0; i_l < used_leptons.size(); i_l++) {
       vector<Particle*>::iterator lepton_finder = find(child_candidates.begin(), child_candidates.end(), used_leptons.at(i_l));
       child_candidates.erase(lepton_finder);  
  }
  return unduplicated_bosons;
}

然后我会在类中使用这个成员函数,就像一样

vector<Boson*> *m_boson_finals_elpair = remove_duplicates(&m_boson_electronPair_candidates, m_all_particle_candidates);
vector<Boson*> *m_boson_finals_mupair = remove_duplicates(&m_boson_muonPair_candidates, m_all_particle_candidates);
vector<Boson*> *m_boson_finals_elneutrino = remove_duplicates(&m_boson_electronNeutrino_candidates, m_all_particle_candidates);
vector<Boson*> *m_boson_finals_muneutrino = remove_duplicates(&m_boson_muonNeutrino_candidates, m_all_particle_candidates);

我的问题是:

m_all_particle_canddates是

vector<Particle*>  m_all_particle_candidates;

每次调用remove_duplicates时是否不同?

我想我想问的是,迭代器lepton_finder是否从向量中删除,而不是从实际对象Particle中删除,因为我已经传递了值?

注意:remove_duplicate函数中存在拼写错误。我传递的是指针而不是值。它应该是值

我对您所说的按值传递和按引用传递有点困惑,所以我将首先对此进行简短解释:

  • 传递值时,调用该方法的变量保持不变(因为副本被传递到被调用的方法中)。但是要小心,这种情况也可能导致严重的性能损失,因为整个变量都是复制的!如果一个向量包含许多元素,这可能需要相当长的时间!传递值在C++中是这样实现的:

  • 当通过引用(或或多或少等效于通过指针)传递时,外部变量也会发生变化,因为您只是将引用传递到方法中,该方法引用的是与原始变量相同的内存实际空间!

因此,基本上不同的是,当使用按值调用时,原始调用方的值保持不变,而当使用按引用调用

现在,需要哪种方法取决于你想要实现什么Pass by Value如果传递到方法中的变量应保持不变(示例中为m_all_particle_candidates)。或者,如果需要更改,则通过引用/指针传递。

如果传入的变量不应更改,但方法中只需要该变量的只读版本,则可以通过使用常量引用来克服通过传递值可能带来的性能问题。然而,在您的情况下,您似乎需要一个完整的副本(意味着一个正常的传递值)。

OP中的代码是否编译?我不这么认为。公平地说,它应该在发布之前通过编译器。

typedef struct {
   long double x, y, z;
} V3;
void fnExpectingPtrToVec(vector<V3> * pvec) {
}
void fnExpectingVec(vector<V3> vec) {
}
void testVecs() {
   vector<V3> v;
   //fnExpectingPtrToVec(v); Does not compile
   fnExpectingPtrToVec(&v);
   fnExpectingVec(v);
}

如果它在第二个参数中期望一个指向向量的指针,而您传入了一个向量,那么这是一个编译错误。

当您将函数固定为接受向量,而不是指向向量的指针,并使用向量调用它时,它将生成一个副本,并且对函数的重复调用将保持m_all_particle_candidates不变。

您没有按值传递向量。

vector<Boson*>* BosonMaker::remove_duplicates(vector<Boson*>* boson_candidates, vector<Particle*> *child_candidates);

将按值vector传递指针。但是,作为原始指针副本的指针将指向与原始指针相同的vector

因此,你基本上是在改变与调用外相同的向量。

要传递值,您需要:

vector<Boson*>* BosonMaker::remove_duplicates(vector<Boson*> boson_candidates, vector<Particle*> child_candidates);

但这样做时要小心。复制会发生,所以如果BosonParticle不是POD类型,您可能需要重写它们的虚拟析构函数、复制构造函数和赋值运算符。