如何存储或转发CRTP模板类的类型

时间:2011-11-15 14:43:47

标签: c++ templates crtp

一般想法:一对班级,一名创造工人的经理。每个都接受一组自定义行为的策略。每个策略都有一个影响管理器的部分(做一些设置)和一个影响worker的部分(添加需要调用并从宿主工作者类中的函数调用的特定工作函数 - 目前通过CRTP完成)

工作程序中使用的策略将始终镜像管理器中的策略。即manager<foo,bar>将创建worker<foo_worker,bar_worker>类型的工作人员。因此,我想在管理器策略中存储工作策略的类型,以便最终用户不必同时指定它们。

以下代码实现了我的代码的简化版本,以演示此问题。查看经理类评论。目前(为了编译示例),经理使工人成为硬编码类型。

问题:如何在类foo中记录模板类foo_worker的类型,管理员可以根据自己的模板参数确定/查找正确的工作类?

typedef foo_worker work_policy;内的

class foo不起作用,因为foo_worker不是类模板。我已经尝试过各种各样的包装类以及typename和template的组合而没有运气。我也尝试将foo_worker作为foo中的嵌套类。

如果我能避免使用C ++ 11,我宁愿不要求C ++ 11,但如果从根本上简化了这个问题,我愿意考虑它。

有没有其他方法来构建这样的系统来避免这个问题?

提前致谢=)

#include <iostream>

// Example policy1 "foo"
template <typename worker_type> 
class foo_worker {
public:
    void policy_work() {
        std::cout << "foo_worker specific work" << std::endl;
        static_cast<worker_type*>(this)->work_finish();
    }
};

class foo {
public:
    foo() {
        std::cout << "foo setup" << std::endl;
    }
};

// Example policy2 "bar"
template <typename worker_type> 
class bar_worker {
public:
    void policy_work() {
        std::cout << "bar_worker specific work" << std::endl;
        static_cast<worker_type*>(this)->work_finish();
    }
};

class bar {
public:
    bar() {
        std::cout << "bar setup" << std::endl;
    }
};

// worker class
template <template <class> class policy1,template <class> class policy2>
class worker 
  : public policy1< worker<policy1,policy2> >,
    public policy2< worker<policy1,policy2> >
{
public:
    typedef policy1< worker<policy1,policy2> > policy1_type;
    typedef policy2< worker<policy1,policy2> > policy2_type;

    void work() {
        std::cout << "start work" << std::endl;
        static_cast<policy1_type*>(this)->policy_work();
        static_cast<policy2_type*>(this)->policy_work();
    }
    void work_finish() {
        std::cout << "finish work" << std::endl;
    }
};

// manager class
template <typename policy1,typename policy2>
class manager : public policy1, public policy2 {
public:
    // this line hard codes workers to the foo_worker and bar_worker policy. 
    // I want to be able to look up which policies to send the worker based 
    // on the policies that was given to the manager.
    typedef worker<bar_worker,foo_worker> worker_type; 

    // Would like to be able to do something like this instead:
    //typedef worker<policy1::work_policy,policy2::work_policy> worker_type;

    manager() : policy1(),policy2() {
        std::cout << "manager setup" << std::endl;
    }

    worker_type* create() {
        return new worker_type();
    }
};

int main() {
    manager<foo,bar> m;
    manager<foo,bar>::worker_type* w = m.create();

    w->work();

    return 0;
}

1 个答案:

答案 0 :(得分:0)

也许你可以使用类型特征之类的东西来解决问题?我希望我能帮助你,所以你怎么看待这样的事情:

template<typename PolicyType>
struct worker_type
{
};

template<>
struct worker_type<foo>
{
    typedef foo_worker type;
};

// .... etc ...

//...

template<typename p1, typename p2>
class manager : public p1, public p2
{
    public:
        typedef worker< typename worker_type<p1>::type,
                        typename worker_type<p2>::type > worker_type;
// ...