2016-04-23 165 views
0
template<class KeyType, class ValueType, class Hash = std::hash<KeyType> > 
class HashMap { 
public: 
    Hash hasher; 

    HashMap(Hash override_ = hasher) { 
     hasher = override_; 
    } 
}; 

這是我的代碼。我期望發生的是,如果構造函數沒有提供默認值hasher,或者將其更改爲new,否則將其更改爲new。我得到的是:invalid use of non-static data member 'hasher'。我已經認爲我可以用Hash()代替hasher作爲默認值;但是如果我不需要默認的對象但是更復雜的東西呢?爲什麼我的第一次嘗試不能編譯?爲什麼我不能將類構造函數參數設置爲默認值?

+0

的構造函數默認參數都解決了對象施工開始前,所以'hasher'不會在那個時候 –

+0

一個存在好的解決方案是2個構造函數,另一個是'HashMap(){}' –

回答

2

您正試圖使用​​構造函數參數的默認值作爲類的成員,而對象尚未創建。除非成員是靜態的,否則這是行不通的。爲了做你想做的事,你可以這樣定義2個構造函數:

#include <map> 
template<class KeyType, class ValueType, class Hash = std::hash<KeyType> > 
class HashMap { 
public: 
    Hash hasher; 

    HashMap(Hash override_) { 
     hasher = override_; 
    } 
    HashMap() { 
    } 
}; 
+0

我不明白的是_why_我不能以這種方式使用它。我已經通過使用'Hash()'作爲默認值規避了這個問題,所以我的問題更多地是關於「爲什麼?」。而不是關於「如何?」。 – Akiiino

+0

@Akiiino'hasher'還沒有創建,那怎麼用呢? – Slava

+0

@Slava但是如果它是'static' ---當我創建第一個'HashMap'時,它還沒有被創建,或者它是什麼? – Akiiino

0

按照標準它是被禁止的。這在C++ 03標準的第8.3.6節中有詳細描述。它基本上相當於任何不依賴於局部範圍內任何表達式的表達式,所以任何依賴局部變量,函數參數或「this」的表達式都將被排除。

0

嗯,你可以做的是這樣的:

template<class KeyType, class ValueType, class Hash = std::hash<KeyType> > 
class HashMap { 
public: 
    Hash hasher; 

    HashMap(Hash override_ = {}) : hasher{std::move(override_)} {} 
}; 

如果沒有提供,默認構造函數被調用。

就個人而言,我認爲最好的辦法是添加默認的構造函數:

template<class KeyType, class ValueType, class Hash = std::hash<KeyType> > 
class HashMap { 
public: 
    Hash hasher; 

    HashMap() = default; 
    HashMap(Hash override_) : hasher{std::move(override_)} {} 
}; 
相關問題