没有模板参数的模板类的容器 [英] Container of template classes without template parameter
问题描述
我想知道您是否可以拥有一个包含具有不同模板参数的对象的容器.
I'm wondering if you can have a container with objects with varying template parameters.
我正在努力实现这样的目标:
I'm trying to achieve something like this:
#include <iostream>
#include <list>
template <class T>
class base
{
public:
T val;
base(T newVal): val(newVal) {};
};
class derived : public base<int>
{
public:
derived(int newVal): base(newVal) {};
};
int main ( void )
{
std::list < base<?> > base_collection;
return 0;
}
我希望我当前的项目尽可能灵活和动态,在需要新的派生类时几乎不需要额外的编码,并且我当前的实现使得存在这样的列表很重要.
I want my current project to be as flexible and dynamic as possible, with little extra coding when a new derived class is necessary, and my current implementation makes it important that such a list exists.
是否有一种常用的、有益的和干净的方式来实现这一目标?
Is there a commonly used, benefiting and clean way of achieving exactly this?
推荐答案
一个可能的实现是使用双重调度:
A possible implementation would be using the double dispatching:
#include <iostream>
#include <list>
struct visitor;
struct dispatchable {
virtual void accept(visitor &v) = 0;
};
template <class>
struct base;
struct visitor {
template<typename T>
void visit(base<T> &);
};
template <class T>
struct base: dispatchable {
T val;
base(T newVal): val(newVal) {};
void accept(visitor &v) override { v.visit(*this); }
};
struct derivedInt : base<int> {
derivedInt(int newVal): base(newVal) {};
};
struct derivedDouble : base<double> {
derivedDouble(double newVal): base(newVal) {};
};
template<>
void visitor::visit(base<int> &) {
std::cout << "int" << std::endl;
}
template<>
void visitor::visit(base<double> &) {
std::cout << "double" << std::endl;
}
int main ( void ) {
visitor v{};
std::list <dispatchable*> coll;
coll.push_back(new derivedInt{42});
coll.push_back(new derivedDouble{.42});
for(auto d: coll) d->accept(v);
}
这样,您只需定义处理您要引入的新 base
类型的专用函数.
举个例子,如果你想使用base
,你必须定义:
This way, you have only to define the specialized function that deals with the new base<T>
type you want to introduce.
As an example, if you want to use base<char>
, you have to define:
template<>
void visitor::visit(base<char> &) {
std::cout << "char" << std::endl;
}
请注意,我假设您想以不同的方式处理 base
的每个特化.否则,定义通用成员函数 visitor::visit
并删除特化就足够了.
Note that I supposed you want to treat each specialization of base<T>
in a different way. Otherwise, it's enough to define the generic member function visitor::visit
and drop the specializations.
旁注:不要使用裸指针.
这是一个例子.在生产代码中,我会改用智能指针.
Side note: do not use naked pointers.
This is an example. In production code, I'd use smart pointers instead.
这篇关于没有模板参数的模板类的容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!