2014-05-02 59 views
0

標準庫忽略實現基本操作爲std::setstd::map繼承初始化從語法的std ::設置或std ::地圖

set<T> set<T>::getUnion(set<T> other) 

bool map<K,V>::contains(K key) 

我知道有冗長和/或這些方法的間接解決方法,但如果我希望我的代碼具有最大的可讀性和表達性,我將不得不從STL繼承,編寫我自己的SetMap類,並自己實現它們。是的,我知道這樣做的說教,但事實是STL是不完整的。

我已經這樣做了,但現在我可以使用,例如,未初始化我的新類,

Set<int> s = {1,2,3,4}; 

如何繼承了std類這些初始化?

+0

'bool map :: contains(K key)'僅在非常狹窄的用例中有用。大多數情況下,您想要訪問給定密鑰的值。 –

+0

所以'vector :: back()'。大多數情況下,您只需要'push_back',迭代或按索引訪問。但是這並沒有阻止STL作者指定「back」。實際情況是,爲'map'實現的任何爲Python'dict'實現的操作都應該實現。 Python'set'也是一樣。問題不在於使用頻率,而在於數據結構所代表的數學,直觀和邏輯結構。 –

回答

3

儘管公開的標準庫中的容器繼承的事實被認爲是一個壞主意,你可以「繼承」的構造函數:

template <typename T> 
struct Set : std::set<T> 
{ 
    using std::set<T>::set; // "inherit" the constructors. 
}; 

然後

Set<int> s{1,6,4,3,3,9}; 

需要注意的是一個更好的辦法可能是爲了實現功能:

template <typename C> 
bool contains(const C& container, const typename C::key_type& key) 
{ 
    return container.count(key); 
} 

and similarly for the union of sets

+1

爲什麼不爲8個容器製作'contains' generic:'template bool contains(const C&c,const typename C :: key_type&k){return c.count(k); }'? –

+0

@DanielFrey好主意。我會編輯。 – juanchopanza

+0

由於存在切片或不正確銷燬的潛力,不鼓勵繼承標準容器,如果您沒有任何添加的數據成員或虛函數,並且派生的析構函數是默認的,則不會造成問題。當然,這意味着你希望在知道這些規則之後維護者也會來。 –

1

gcc 4.7.x,你必須調用initializer_list構造函數setmap

template <typename T> 
class Set : public set<T> { 
public: 
    Set(){ 
     set<T>::set(); 
    } 
    Set(initializer_list<T> iList) { 
     set<T>::set(iList); 
    } 
}; 

允許

Set<int> s = {1,2,3,4}; 

但大部分經過反覆試驗,我不能找到一種方法,爲std::map做這個。

此外,它禁用所有其他構造函數,要求我重新實現它們,我還沒有完成任務,所以我現在就放棄初始化列表。歡迎任何人提交一個答案,將所有構造函數重新實現爲Set,我將選擇它作爲答案。

+0

您應該在問題中添加非常具體的要求。基本上,你需要一些支持C++ 11減去繼承構造函數的東西。 – juanchopanza

+0

是的,它看起來就像使用gcc 4.8會解決這些問題。然後我可以使用你的答案,我已經驗證了在另一臺機器上使用更新的編譯器。 –