简体   繁体   English

在同一个容器中添加一个模板class的不同实例,调用一个模板class的方法

[英]Add different instantiations of a template class in the same container and call a template class method

Suppose I have these classes:假设我有这些课程:

class A
{
   // virtual methods
};

template<typename T>
class B : public A
{
    void ANewMethodSpecificOfClassB(...){...};
}

I would like to add a subset of B classes into a container and from there, call ANewMethodSpecificOfClassB .我想将 B 类的一个子集添加到容器中,然后从那里调用ANewMethodSpecificOfClassB

For example, given:例如,给定:

B<instanciation1> south_park;
B<instanciatoin2> family_guy;

suppose I want to put B<instanciation1> and B<instanciation2> in the same container (for example a vector): I cannot declare a std::vector<B> because B is not a real class, only B<instanciation1> and B<instanciation2> are.假设我想将B<instanciation1>B<instanciation2>放在同一个容器中(例如一个向量):我不能声明一个std::vector<B>因为B不是真正的 class,只有B<instanciation1>B<instanciation2>是。

Then I thought to define a vector using a (shared) pointer to the base class. However, doing so gives error when calling ANewMethodSpecificOfClassB because the method is not defined in the base class (and no, I can't modify the base class adding the method there).然后我想使用指向基数 class 的(共享)指针定义一个向量。但是,这样做会在调用ANewMethodSpecificOfClassB时出错,因为该方法未在基数 class 中定义(不,我无法修改基数 class 添加那里的方法)。

Is there a way create a container with two different instances of a template classes and call a method that all of the instantiated classes have but not the parent class of the template class?有没有办法用模板类的两个不同实例创建一个容器,并调用所有实例化类都有但模板 class 的父类 class 没有的方法?

There are (at least) two ways around this:有(至少)两种解决方法:

  1. You might define an intermediate class, AWithSpecificMethod :您可以定义一个中间值 class, AWithSpecificMethod
class AWithSpecificMethod {
protected:
    virtual ANewMethodSpecificOfClassB() const = 0;
};

Then have B<> descend either from A or from AWithSpecificMethod .然后让B<>AAWithSpecificMethod下降。 You can do that using std::conditional<> , std::is_same<> et.您可以使用std::conditional<>std::is_same<>等来做到这一点。 al.阿尔。

However, this way of solving it, at some point, creates several interfaces and immediate classes which are not true abstractions, just a notation of existence of method.然而,这种解决它的方法在某些时候会创建几个接口和直接类,它们不是真正的抽象,只是方法存在的符号。 Also, it's virtual => likely very slow.此外,它是虚拟的 => 可能非常慢。

  1. You might store them in an std::variant<B<T1>, B<T2>, ...> and reconsider even if A is necessary as an interface class. This works if you know the possible types T1, T2, ... that you intend to work with (practically almost always).您可以将它们存储在std::variant<B<T1>, B<T2>, ...>并重新考虑,即使A作为接口 class 是必需的。如果您知道可能的类型 T1, T2, ,这将起作用。 .. 你打算与之合作(实际上几乎总是)。 You can visit a variant using std::visit , which you usually pass a lambda and the variant:您可以使用std::visit访问variant ,您通常会传递 lambda 和变体:
std::variant<B<int>, B<char>> var;
std::visit([&](auto const& actual) {
    // here actual is the concrete type
    // either B<int> const& or B<char>&
}, var);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM