困惑?我也是... 考虑以下内容
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/