如何在编译时从类型列表中生成类型?

时间:2013-07-01 19:58:23

标签: c++ mixins template-meta-programming

我继承了Table Data Gateway实现,我正在尝试将一些运行时错误转换为编译时错误。表和类之间存在简单的一对一映射,但并非所有CRUD操作都适用于所有类型。有一个“经理”类模板(以简化形式)看起来像

template <typename T>
class object_manager
{
public:
    void create(const T&){ /* SQL CREATE */ }
    void update(const T&){ /* SQL UPDATE */ }
    void del(const T&){ /* SQL DELETE */ }
    template <OutIt> OutIt read(OutIt) const {/* SQL SELECT */}
private:
    some_db_connection& m_db;
};

我想切换到mixin类型的实现,这样每个持久化类型都有一个关联的object_manager,它只从对该类型对象有效的操作构建。我发现如果我将CRUD函数分解为他们自己的类,那么

template <typename T>
class object_manager
{
public:
    typedef T object_type;
protected:
    some_db_connection& m_db;
};

template <typename Base>
class create_mixin : public Base
{
public:
    typedef Base::object_type object_type;
    void create(const object_type&) { /* sql INSERT */ }
};

template <typename Base>
class read_mixin : public Base
{
public:
    typedef Base::object_type object_type;
    template <OutIt> OutIt read(OutIt) const {/* SQL SELECT */}
};

template <typename Base>
class update_mixin : public Base
{
public:
    typedef Base::object_type object_type;
    void update(const object_type&) {/* SQL UPDATE*/}
};

template <typename Base>
class delete_mixin : public Base
{
public:
    typedef Base::object_type object_type;
    void del(const object_type&) {/* SQL DELETE*/}
};

然后我能够生成一个只有有效操作的类型,从而在编译类型中找到不正确的函数调用(例如尝试更新不可变类型)

//read-only
read_mixin<object_manager<some_persistent_type>> read_only_mgr;

//un-deletable
create_mixin<read_mixin<update_mixin<object_manager<some_persistent_type>>>> undeletable_mgr;

我希望能够在编译时从boost :: mpl :: vector生成这些object_manager类型,这样我就可以为列出的持久化类型创建一个traits类。有效的操作。

struct op_create;
struct op_read;
struct op_update;
struct op_delete;

template <typename T>
struct my_traits
{
    typedef boost::mpl::vector<op_create, op_read, op_delete> valid_operations;
};

将某些符号名称(例如op_read,op_create等)映射到实际的mixin类是微不足道的,但我正在努力的是如何重新创建第三个代码块中显示的类型。我有一个模糊的概念,即boost :: mpl :: inherit_linearly会起作用,但我还不清楚所有部分是如何组合在一起的。

我应该提到我可以访问一个相对现代的Boost而不是c ++ 11。

0 个答案:

没有答案