c++ - 构造函数初始化列表中的非成员初始化

标签 c++ c++11 initializer-list

困惑?我也是... 考虑以下内容

typedef std::map<std::string , double> Thresholds;

class Foo 
{
    public: 
        Foo( const double & _toxicThres , const double & _zeroThres )
    : thresholds
    (
        MapInitializer<std::string , double>()
            .Add("toxic" , _toxicThres)
            .Add("zero" , _zeroThres)
    )

    private:
       Thresholds thresholds; 
};

上面的代码运行良好,并在构造函数的成员初始化列表中初始化了一个 std::map。现在考虑一下:

typedef std::map<std::string , double> Thresholds;
struct CommonData
{
    Thresholds thresholds;
};

class Foo //a mixin
{
    public: 
        Foo( Thresholds & thresholds , const double & _toxicThres , const double & _zeroThres )
    : thresholds
    (
        MapInitializer<std::string , double>()
            .Add("toxic" , _toxicThres)
            .Add("zero" , _zeroThres)
    )
};

class Bar //another mixin
{
    public: 
        Bar( Thresholds & thresholds , const double & _warningThres , const double & _zeroThres)
    : thresholds
    (
        MapInitializer<std::string , double>()
            .Add("warning" , _warningThres)
            .Add("zero" , _zeroThres)
    )
};

class OtherGasThreshold{/*...*/}; //yet another mixin, etc...

template<typename ThresholdMixin> //Foo , Bar , or others ...
class ThresholdSensor : public ThresholdMixin 
{
    public:
        ThresholdSensor(double val1 , double val2) 
            : ThresholdMixin(cd.thresholds, val1 , val2)
        {}

    private:
        CommonData cd;
};

注意 MapIniializer 代码来自 here , 并且是

template<class K, class V>
class MapInitializer
{
    std::map<K,V> m;
public:
    operator std::map<K,V>() const 
    { 
        return m; 
    }

    MapInitializer& Add( const K& k, const V& v )
    {
        m[ k ] = v;
        return *this;
    }
};

当然,上面的代码不会编译,但是有什么方法可以在构造函数初始化期间的其中一个混入中的 ThresholdSensor::CommonData 中初始化映射。即我可以通过引用传递映射,在 mixins 构造函数中初始化它吗?

最佳答案

基本子对象在数据成员之前构造,因此通常基本初始化程序不能使用派生数据成员。

我会保持简单并有一个普通的成员函数:

struct Foo
{
    void Init(Thresholds & thresholds)
    {
         thresholds.emplace("foo", 1.0);
         thresholds.emplace("bar", 1.5);
    }

    // ...
};

template <typename Mx>
struct Thing : Mx
{
    Thresholds thresholds;

    Thing() { Mx::Init(thresholds); }
    //        ^^^^^^^^^^^^^^^^^^^^^

    // ...
};

用法:

Thing<Foo> x;

关于c++ - 构造函数初始化列表中的非成员初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39605765/

相关文章:

c++ - 我可以从initializer_list实例化一个数组吗?

c++ - 无法正确计算公式

c++ - 配置:错误:无法链接到 libboost_atomic

python - 在 C++ 中为 Tensorflow 模型定义一个 feed_dict

c++ - 如何调用传递模板成员方法作为参数

C++ 多线程将模板化的 std::bind 提供给另一个线程

c++ - Valgrind 错误 : in use at exit: 72, 704 字节 C++ 初始化列表异常与 char*

c++ - 深层复制构造函数 - 类 C++ 中的动态数组无效的 free()/delete/delete[]/realloc()

c++ - 打印 unordered_set 的元素

c++ - 围绕标量初始值设定项错误的大括号