2016-04-23 117 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_)} {} 
}; 
相关问题