我如何调用从类型列表中的每个继承类型非默认构造函数? [英] How do I invoke a non-default constructor for each inherited type from a type list?

查看:88
本文介绍了我如何调用从类型列表中的每个继承类型非默认构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用升压类型串执行以下方式的政策模式。

I'm using a boost typelist to implement the policy pattern in the following manner.

using namespace boost::mpl;

template <typename PolicyTypeList = boost::mpl::vector<> >
class Host : public inherit_linearly<PolicyTypeList, inherit<_1, _2> >::type
{
public:
    Host() : m_expensiveType(/* ... */) { }

private:
    const ExpensiveType m_expensiveType;
};

主机类知道如何创建 ExpensiveType 的一个实例,这是一个代价高昂的操作,每一个政策类公开的功能来使用它。策略类总是有最低限度以下示例策略中定义的构造。

The Host class knows how to create an instance of ExpensiveType, which is a costly operation, and each policy class exposes functionality to use it. A policy class will always minimally have the constructor defined in the following sample policy.

struct SamplePolicy
{
    SamplePolicy(const ExpensiveType& expensiveType)
        : m_expensiveType(expensiveType) { }

    void DoSomething()
    {
        m_expensiveType.f();
        // ...
    }

private:
    const ExpensiveType& m_expensiveType;
};

是否有可能以这样的方式来调用每一个给定政策的构造函数定义主机的构造函数?如果没有涉及的类型列表中,这是很容易的,因为每个政策的类型是明确已知的。

Is it possible to define the constructor of Host in such a way to call the constructor of each given policy? If the type list was not involved, this is very easy since the type of each policy is explicitly known.

template <typename PolicyA, typename PolicyB>
class Host : public PolicyA, public PolicyB
{
public:
    Host() :
        m_expensiveType(/* ... */),
        PolicyA(m_expensiveType),
        PolicyB(m_expensiveType) { }

private:
    const ExpensiveType m_expensiveType;
};

借助提振:: MPL :: for_each的算法看起来很有希望,但我不能换我围​​绕如何使用它的头解决这个问题。

The boost::mpl::for_each algorithm looks promising, but I can't wrap my head around how to use it to solve this problem.

推荐答案

我无法抗拒的诱惑,看看它如何能与 inherit_linearly 来完成。
原来是不那么糟糕,恕我直言:

I could not resist the temptation to see how it could be done with inherit_linearly. Turns out to be not that bad, IMHO:

template<class Base, class Self>
struct PolicyWrapper : Base, Self
{
    PolicyWrapper(const ExpensiveType& E)
        : Base(E), Self(E)
    {}
};

struct EmptyWrapper
{
    EmptyWrapper(const ExpensiveType& E)
    {}
};

template <typename PolicyTypeList = boost::mpl::vector<> >
class Host : 
    public inherit_linearly<
       PolicyTypeList, 
       PolicyWrapper<_1, _2>, 
       EmptyWrapper
    >::type
{

typedef typename inherit_linearly<
    PolicyTypeList, 
    PolicyWrapper<_1, _2>, 
    EmptyWrapper
>::type BaseType;

public:
    Host() : BaseType(m_expensiveType)
    {}

private:
    const ExpensiveType m_expensiveType;
};

一个警告,虽然:传递一个参考喜欢的是在主机构造函数做一个未初始化的成员是非常脆弱的。
如果,例如,一个写策略是这样的:

A warning though: Passing a reference to an uninitialized member like what is done in the Host ctor is very fragile. If, for example, one writes a Policy like this:

struct BadPolicy
{
    BadPolicy(const ExpensiveType& E)
    : m_expensiveType(E)
    {}

    ExpensiveType m_expensiveType;
};

不好的事情会发生,因为ExpensiveType的副本构造函数将未初始化的对象调用。

bad things will happen, as the copy ctor of ExpensiveType will be invoked with an uninitialized object.

这篇关于我如何调用从类型列表中的每个继承类型非默认构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆