[英]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:有(至少)两种解决方法:
AWithSpecificMethod
:您可以定义一个中间值 class, AWithSpecificMethod
:class AWithSpecificMethod {
protected:
virtual ANewMethodSpecificOfClassB() const = 0;
};
Then have B<>
descend either from A
or from AWithSpecificMethod
.然后让B<>
从A
或AWithSpecificMethod
下降。 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.此外,它是虚拟的 => 可能非常慢。
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.