2012-11-26 36 views
3

我创造了这个模板函数查找并从shared_ptr的期广义函数在STL集合操作所有集合

template<class T> 
bool FindAndDelete(set<shared_ptr<T>>& collection, shared_ptr<T> item) 
{ 
    auto foundItem = find(collection.begin(), collection.end(), item); 
    if(foundItem != collection.end()) 
    { 
     collection.erase(foundItem); 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

问题的集合中删除和项目: 我怎么能概括它更涵盖所有集合? (向量,列表等)

例如

template<class K, class T> 
bool FindAndDelete(K<shared_ptr<T>>& collection, shared_ptr<T> item); 

注:我来自C#,所以也许代码是有点过:)纠正我,请

+2

如果您不熟悉C++,可能会根据自己的喜好使用太多模板,但是[此视频(从开始到大约14分钟)](http://channel9.msdn.com/Series/C9-Lectures -Stephan-T-Lavavej-Standard-Template-Library-STL-/C9-Lectures-Stephan-T-Lavavej-Standard-Template-Library-STL-3-of-n)在Channel9上Stephan T. Lavavej给出了一个有趣的方法创建一些用于vector,deque,list,forward_list,set,multiset,map,multimap和无序变体的函数'erase'(删除特定值)和'erase_if'(删除满足谓词的任何值) 。 – 2012-11-26 12:37:57

+0

@llonesmiz谢谢,实际上我看了他关于智能指针和收藏的视频,非常具有说服力!我喜欢模板,但有时会让我困惑,因为我习惯于在C#中使用更简单的泛型类型。 –

回答

6

如果你想从一个容器中删除元素,那么像这样的工作:

template<class K> 
bool FindAndDelete(K& collection, typename K::value_type item); 

记住,在地图是一个std::pair<key_type, mapped_type>,所以你可能要为那些提供特殊版本,例如

template<typename T, typename K> 
bool FindAndDelete(std::map<T,K>K& collection, 
        typename std::map::<T,K>::key_type key); 

,同样为std::multimap和C++ 11个std::unordered_*变种。这些容器的find成员函数的效率比std::find更高,因此有必要专门实现findAndDelete来利用此功能。

您也可以看看std::remove_iferase remove idiom作为您的非关联容器实现的替代方案。在重复的情况下,这可能会更有效。

+0

您将如何限制在集合上使用它?我的意思是,在C#中,你可以使用'class Clazz 其中T:ICollection'(参见http://msdn.microsoft.com/en-us/library/d5x73970.aspx) –

+1

@mizi_sk你不会,因为集合没有共同的基类或接口。编译器会告诉你,如果你做错了什么。或者你可以使用'SFINAE'来检查T是否具有所有容器都有的属性。 – juanchopanza

1
template <template<typename> class K, typename T> 
bool FindAndDelete(K<shared_ptr<T> > &collection, shared_ptr<T> item);