使用枚举和模板参数正确定义显式默认构造函数

Posted

技术标签:

【中文标题】使用枚举和模板参数正确定义显式默认构造函数【英文标题】:Correct definition of explicit default constructor with enum and template arguments 【发布时间】:2020-05-06 17:57:21 【问题描述】:

我有一个带有子类的基类Method

auto harmonic_force = [](const double& q, const double& k)return -k*q;;
enum SplittingAB SS,L42 ;

class Method

public:
    ~Method() = default;
    virtual void evolute( std::vector<std::pair<double,double>> &qp, int T) const = 0;
;


template <typename Function>
class MiddleO : public Method
public:
    MiddleO() = default;
    explicit MiddleO(SplittingAB mmo_=SS, const double& a_=-1.0, const double& b_=1.0, const Function& force_=harmonic_force, const double& k_=1.0, const double& gamma_=1.0, const double& kBT_=1.0);

    void evolute( std::vector<std::pair<double,double>> &qp,  int T) const override;

    std::string get_name(SplittingAB m) const 
        switch (m)
            case SplittingAB:: SS:
                return "MethodsMiddleO_SS";
            
            case SplittingAB ::L42:
                return "MethodsMiddleO_L42";
            
        
    
private:
    SplittingAB  mmo;
    const double k, gamma, kBT, a, b;
    double L = 1.0;
    Function&  force;
;

我对构造函数的定义是:

template<typename Function>
MiddleO<Function>::MiddleO(SplittingAB mmo_, const double &a_, const double &b_, const Function &force_,
                       const double &k_, const double &gamma_, const double &kBT_)
    : Method(), mmo(mmo_), a(a_), b(b_), force(force_), k(k_), gamma(gamma_), kBT(kBT_)  L=b-a; 
    我收到错误binding reference of type ‘&lt;lambda(double, double)&gt;&amp;’ to ‘const&lt;lambda(double, double)&gt;’ discards qualifiers。我不明白我应该如何正确初始化力。 我也收到了Constructor does not initialize these fields: mmo的评论

编辑: 在我的main() 函数中,我写道:

auto cos_force = [](double q, const double k)return -q*q*q*k - 5.0*cos(1+5.0*q);;
int main()
     double a = -3.5;
     double b = 3.5;

    double const k = 1.0;
    double const gamma = 1.0;
    double const kBT=1.0;
    std::vector<std::pair<double,double>> qp;
    qp.reserve(T+1);
    qp.emplace_back(0.0,0.1);

    SplittingAB sm = SS;
    MiddleO<decltype(cos_force)> obj(sm, a,  b, cos_force , k, gamma,kBT);
   ...

【问题讨论】:

这编译得很好。你能分享给出错误的实例吗? 编译器参数 const Function &amp;force_ 必须更改为 Function &amp;force_ 才能绑定此引用 - 或将字段更改为 const Function&amp; force; 我在main() 函数中收到SplittingAB sm = SS; MiddleO&lt;decltype(cos_force)&gt; obj(sm, a, b, cos_force , k, gamma,kBT); 的错误。 那么请提供cos_force的定义。了解如何制作minimal-reproducible-example 【参考方案1】:

问题 1

编译器正确地报告了一个错误,因为您尝试使用Function const&amp; 初始化Function&amp;。如果允许,它不会保留原始对象的const-ness。

除非性能对您的用例来说是一个经过验证的问题,否则请更改

Function&  force;

Function  force;

问题 2

罢工>

添加代码来初始化成员。

template<typename Function>
MiddleO<Function>::MiddleO(SplittingAB mmo_, const double &a_, const double &b_,
                           const Function &force_, const double &k_,
                           const double &gamma_, const double &kBT_)
    : Method(), mmo(mmo_), a(a_), b(b_), force(force_), k(k_),
      gamma(gamma_), kBT(kBT_), mmo(SS)  L=b-a; 
                             // ^^^^^^^

也许编译器在抱怨默认构造函数。

还有,

MiddleO() = default;

不对。这并没有为引用成员提供初始化方法。编译器应该为此报告错误。

【讨论】:

谢谢你的回答,为什么写mmo(mmo_)来初始化字段是不够的。 @Suslik,对不起,这是我的错误。也许编译器在抱怨默认构造函数。 啊哈,谢谢。您的第一个提示解决了我的一个问题。

以上是关于使用枚举和模板参数正确定义显式默认构造函数的主要内容,如果未能解决你的问题,请参考以下文章

C++——构造函数和析构函数

使用显式定义的默认构造函数将 unique_ptr 的类内成员初始化程序设置为 nullptr 错误

构造函数必须显式初始化没有默认构造函数的成员

C++17 中的显式默认构造函数

C++调用父类的构造函数规则

构造方法