将多种类型的模板化类存储到容器中 [英] Storing multiple types of a templated class into a container

查看:103
本文介绍了将多种类型的模板化类存储到容器中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个带有模板的课程:

If I have a class with a template:

template<typename T>
class foo{
    T m_a;

    foo(T a){
        m_a = a;
    };

    ~foo(){

    };
};

是否可以存储它的多个变体?

Is there a way to store multiple variation of it ?

例如一个可以存储指向 foo< int> foo<字符串> 同时?

For example a vector that can store a pointer to foo< int > and foo< string > at the same time ?

编辑更多信息

我想隐藏它的实现:

EventListener<string> ev1;
EventListener<int, int> ev2;
EventListener<int, string, double> ev3;

ev1(&Events::nameChange, &nameChangeCallback);
ev2(&Events::healthChange, &healthChangeCallback);
ev3(&Events::newUser, &newUserCallback);

ev1.processEvents();
ev2.processEvents();
ev3.processEvents();

为此:

EventManager em;
em.listen(&Events::nameChange, &nameChangeCallback);
em.listen(&Events::healthChange, &healthChangeCallback);
em.listen(&Events::newUser, &newUserCallback);
em.processEvents();

EventManager需要创建EventListener并将其存储到向量中,以便能够记住它们并将其删除。

EventManager needs to create and store EventListeners into a vector to be able to remember them and delete them in the destructor.

那就是我被困住的地方。

That's where I'm stuck.

推荐答案

如果你想要例如 std :: vector< foo< T&*;> ,那么您需要使用非模板基类。它将需要使用动态调度,因此所有公共接口都应声明为 virtual

If you want e.g. std::vector<foo<T>*>, then you need to use a non-templated base class. It will need to use dynamic dispatch, so all of the public interface should be declared virtual.

struct foo_base {
    virtual ~foo_base() {}
    virtual void something() = 0;
};

template <typename T>
struct foo : foo_base {
    // ...
    void something() { /* do something with T */ }
};

然后您的容器为 std :: vector< foo_base *> 。另一种也许更好的方法是使用 boost :: variant 。这限制了可以存储的类型数量,但同时不需要基类和虚拟接口。

Then your container is std::vector<foo_base*>. Another, perhaps better, way, is to use boost::variant. This limits the number of types you can store, but at the same time doesn't require base class and virtual interface.

typedef boost::variant<foo<int>, foo<std::string>> foo_variants;
std::vector<foo_variants> v;

第三种方法是使用 boost :: any ,但是无论您在哪里使用,都需要 boost :: any_cast ,并允许绝对值存储在向量中。

Third way is to use boost::any, but that will require boost::any_cast wherever you use them, and allow absolutely anything to be stored in the vector.

std::vector<boost::any> v;

这篇关于将多种类型的模板化类存储到容器中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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