2011-11-03 58 views
1

在C++中,除了我的问题Erasing element from Vector之外,我怎样才能将用于从矢量中删除元素的方法推广到具有以下参数的函数中:矢量和要删除的元素从这个向量?函数中的向量中的擦除元素

bool removeElementFromVector(vector * collection, void * element) { 
    for(int i=0; i<collection->size(); i++){ 
     if (collection[i]==element){ 
      swap(collection[i], collection.back()); 
      collection.pop_back(); 
      return true; 
     } 
    } 
} 

我在这里的问题是我不知道的参数列表如何有看起来像为了能够为这个与任何工作vector<whatever*>和任何对象whatever!?

编辑:解决方案:

myfunctions.h

template <typename T> 
bool removeElementFromVector(vector<T> & collection, T const & element) { 
    // for... 
} 

myclass.h

#include "myfunctions.h" 
public: 
vector<Item*> items;       
void removeItem(Item * item);   

myclass.cpp

#include "myclass.h" 
void myclass::removeItem(Item * item) { 
    removeElementFromVector(this->items, item); 
} 
+1

矢量类是什么样的? std :: vector肯定会采用vector-> erase(element);例如。 – Valmond

+2

@Valmond,'vector :: erase'是'O(n)',OP的方法是'O(1)'(尽管它扰乱了元素的顺序)。 – avakar

+0

OP不关心订单;) – Ben

回答

5

在C++中,编写通用代码的类型安全方式不适用于不同类型的应用程序,而不是通过void*,而是模板。你的具体情况:

template <typename T> 
void removeElement(std::vector<T> & collection, T const & element) { 
    collection.erase(std::remove(collection.begin(), collection.end(), element), 
        collection.end()); 
} 

通过使用包含的类型T模板,你使它通用。在内部,从矢量中去除元素的成语是erase-remove成语,它将删除匹配的元素,并向前压缩其余元素以保持相对顺序。我改变了引用的指针。如果你的容器持有指向给定类型的指针,并且传递的元素是指向该类型的指针,编译器会为你推断出Ttype*,但上面的代码也适用于不包含指针的容器(稍微多一点通用)

如果相对顺序不重要,可以使用与问题中相同的循环,这样会更有效(副本数量更少)。

+0

为什么我应该使用引用而不是指针?我试着用这个如下:'vector items; ();}但是我得到的编译器错误:未定义的引用'bool removeElement (std :: vector >&,Item * const&)'任何帮助? – Ben

+1

@Ben:“为什么我应该使用引用而不是指针?”引用更容易正确使用,因为您不必处理它们为空的可能性,并且不会意外更改它们引用的对象。 –

+1

@Ben:“有帮助吗?”我猜你把模板定义放在一个源文件中。你必须把它放在一个头文件中,并将其包含在使用它的任何文件中。 –

5

你应该使功能成为一个模板:

template <typename T> 
bool removeElementFromVector(vector<T> & collection, T const & element); 

另外,不要使用指针。

1

使函数模板:

template <typename T> 
bool removeElementFromVector(vector<T*> * collection, T* element) { 
    for(int i=0; i<collection->size(); i++){ 
     if (collection[i]==element){ 
      swap(collection[i], collection.back()); 
      collection.pop_back(); 
      return true; 
     } 
    } 
} 

在另一方面,你的代码是与所有这些指针相当可怕的。标准容器旨在存储完整的对象,而不仅仅是指针。同样,element参数可能很容易成为(const)参考。