没有模板参数的模板类的容器 [英] Container of template classes without template parameter

查看:65
本文介绍了没有模板参数的模板类的容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道您是否可以拥有一个包含具有不同模板参数的对象的容器.

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屋!

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