C++ 为什么可以';我是否将类构造函数参数设置为默认值? 模板 类哈希映射{ 公众: 散列哈希器; HashMap(散列覆盖\散列器){ hasher=override_u2;; } };

C++ 为什么可以';我是否将类构造函数参数设置为默认值? 模板 类哈希映射{ 公众: 散列哈希器; HashMap(散列覆盖\散列器){ hasher=override_u2;; } };,c++,class,constructor,default,C++,Class,Constructor,Default,这是我的密码。我希望发生的是,如果构造函数没有提供任何值,我将保留hasher的默认值,否则将其更改为new。我得到的是:对非静态数据成员“hasher”的使用无效。。我已经想到可以用Hash()替换hasher作为默认值;但是如果我不需要一个默认的散列对象,而是需要一个更复杂的对象呢?为什么我的第一次尝试没有编译?当对象尚未创建时,您试图将类的成员用作构造函数参数的默认值。除非成员是静态的,否则无法工作。为了实现所需的功能,可以通过以下方式定义2个构造函数: template<class

这是我的密码。我希望发生的是,如果构造函数没有提供任何值,我将保留
hasher
的默认值,否则将其更改为new。我得到的是:
对非静态数据成员“hasher”的使用无效。
。我已经想到可以用
Hash()
替换
hasher
作为默认值;但是如果我不需要一个默认的
散列
对象,而是需要一个更复杂的对象呢?为什么我的第一次尝试没有编译?

当对象尚未创建时,您试图将类的成员用作构造函数参数的默认值。除非成员是静态的,否则无法工作。为了实现所需的功能,可以通过以下方式定义2个构造函数:

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

    HashMap(Hash override_ = hasher) {
        hasher = override_;
    }
};
#包括
模板
类哈希映射{
公众:
散列哈希器;
哈希映射(哈希覆盖){
hasher=override_u2;;
}
HashMap(){
}
};

当对象尚未创建时,您试图将类的成员用作构造函数参数的默认值。除非成员是静态的,否则无法工作。为了实现所需的功能,可以通过以下方式定义2个构造函数:

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

    HashMap(Hash override_ = hasher) {
        hasher = override_;
    }
};
#包括
模板
类哈希映射{
公众:
散列哈希器;
哈希映射(哈希覆盖){
hasher=override_u2;;
}
HashMap(){
}
};

根据标准,这是禁止的。这在C++03标准的第8.3.6节中有详细说明。它基本上等于任何不依赖于局部范围内任何内容的表达式,因此任何依赖于局部变量、函数参数或“this”的表达式都被排除在外。

根据标准,这是禁止的。这在C++03标准的第8.3.6节中有详细说明。它基本上等于任何不依赖于局部范围内任何内容的表达式,因此任何依赖于局部变量、函数参数或“this”的表达式都被排除在外。

好吧,您可以做的是:

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

    HashMap(Hash override_) {
        hasher = override_;
    }
    HashMap() {
    }
};
模板
类哈希映射{
公众:
散列哈希器;
HashMap(哈希覆盖){}:哈希器{std::move(覆盖)}{
};
如果未提供,则调用默认构造函数

我个人认为最好的选择是添加默认构造函数:

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

    HashMap(Hash override_ = {}) : hasher{std::move(override_)} {}
};
模板
类哈希映射{
公众:
散列哈希器;
HashMap()=默认值;
HashMap(Hash override):hasher{std::move(override)}{
};

好吧,你能做的是:

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

    HashMap(Hash override_) {
        hasher = override_;
    }
    HashMap() {
    }
};
模板
类哈希映射{
公众:
散列哈希器;
HashMap(哈希覆盖){}:哈希器{std::move(覆盖)}{
};
如果未提供,则调用默认构造函数

我个人认为最好的选择是添加默认构造函数:

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

    HashMap(Hash override_ = {}) : hasher{std::move(override_)} {}
};
模板
类哈希映射{
公众:
散列哈希器;
HashMap()=默认值;
HashMap(Hash override):hasher{std::move(override)}{
};

我不明白的是为什么我不能这样使用它。我已经通过使用
Hash()
作为默认值绕过了这个问题,所以我的问题更多的是关于“为什么?”而不是关于“如何?”。@Akiiino
hasher
此时还没有创建,我们将如何使用它?@Slava但是如果它是
静态的
——当我创建第一个
HashMap
时,该怎么办,它还没有创建,或者是吗?@Akiiino:如果成员是静态的,则在程序初始化时创建,不需要实例;非静态成员是在对象实例化时创建的。@shrike您确定是这样吗?由于我的类有模板参数,并且具有不同模板参数的不同实例不共享它们的
静态
s,因此似乎不太可能为每个可能的参数组合生成
静态
变量。我不明白的是为什么我不能以这种方式使用它。我已经通过使用
Hash()
作为默认值绕过了这个问题,所以我的问题更多的是关于“为什么?”而不是关于“如何?”。@Akiiino
hasher
此时还没有创建,我们将如何使用它?@Slava但是如果它是
静态的
——当我创建第一个
HashMap
时,该怎么办,它还没有创建,或者是吗?@Akiiino:如果成员是静态的,则在程序初始化时创建,不需要实例;非静态成员是在对象实例化时创建的。@shrike您确定是这样吗?由于我的类有模板参数,并且具有不同模板参数的不同实例不共享它们的
静态
s,似乎不太可能为每个可能的参数组合生成一个
静态
变量。构造函数的默认参数在对象构造开始之前解析,因此
hasher
在当时不存在一个好的解决方案是使用两个构造函数,另一个是
HashMap(){}
构造函数的默认参数是在对象构造开始之前解析的,因此当时不存在
hasher
一个好的解决方案是两个构造函数,另一个是
HashMap(){}