[英]polymorphism with sub-classes of different template type
I've got class with template and some classes inherit from him. 我有带有模板的课程,有些课程是从他那里继承的。 We want to create instance of the father class without declaring its template type, and call a function returning the template type.
我们要创建父类的实例而不声明其模板类型,并调用一个返回模板类型的函数。
Example: 例:
class FatherWrap {
virtual ~FatherWrap() = default;
};
template<typename T>
class FatherClass : public FatherWrap
{
virtual T getValue();
};
class SonClass1 : public FatherClass<int>
{
int getValue() override;
};
class SonClass2 : public FatherClass<string>
{
string getValue() override;
};
int main()
{
FatherWrap* ch = new SonClass1();
T a = ch->getValue; // What to do instead of T.
}
Let's say you have: 假设您有:
B
B
I<T>
inheriting from B
B
继承的中间模板类I<T>
D1
, D2
, etc. each of which inherits from a specialization of I
D1
, D2
等,每个都继承自I
的专业化 You want to write some code in terms of B
. 您想根据
B
编写一些代码。 You can do that--but you have to limit yourself to using the API that B
defines. 您可以做到这一点-但您必须限制自己使用
B
定义的API。 The methods of B
can be virtual, and the implementations/overrides of those methods in I<T>
and Dx
can use the type T
, but those types can't be exposed to a component the only knows about B
. B
的方法可以是虚拟的,并且I<T>
和Dx
中这些方法的实现/重写可以使用类型T
,但那些类型不能暴露给仅了解B
的组件。
If you want to write some logic that uses T
, then that logic needs to be either in a method of I<T>
, or in a template function that is itself parameterized with a class type: 如果要编写一些使用
T
逻辑,则该逻辑必须在I<T>
的方法中,或者在本身使用类类型参数化的模板函数中:
template<class U>
U someTypeSpecificLogic(I<U> intermediate) {
// can call methods that accept/return U here
}
You can't write logic in terms of B
that depends on the type T
because that type is only defined for the subclass I<T>
. 您不能使用依赖于类型
T
的B
来编写逻辑,因为该类型仅为子类I<T>
定义。 Consider that the B
you have be a different subclass of B
and not an I<T>
at all. 认为
B
你是一个不同的子类, B
,而不是I<T>
在所有。
You could skip the FatherWrap
entirely and make the base class return a variant: 您可以完全跳过
FatherWrap
,并使基类返回一个变体:
struct FatherClass : FatherWrap {
virtual std::variant<int, std::string> getValue();
};
struct SonClass1 : FatherClass {
std::variant<int, std::string> getValue() override {
return "some text";
}
};
struct SonClass2 : FatherClass {
std::variant<int, std::string> getValue() override {
return 95;
}
};
Alternatively, you could template any code that uses SonClass
: 另外,您可以模板化任何使用
SonClass
代码:
struct SonClass1 { // no parent.
std::string getValue() {
return "some text";
}
};
struct SonClass2 { // no parent.
int getValue() {
return 95;
}
};
template<typename T>
void useSonClass(T& son) {
// value may be int or string.
auto value = son.getValue();
}
int main() {
SonClass1 sc1;
SonClass2 sc2;
useSonClass(sc1);
useSonClass(sc2);
}
If you want to contain it, just use a variant: 如果要包含它,只需使用一个变体:
int main() {
std::variant<SonClass1, SonClass2> sc = SonClass2{};
std::visit(
[](auto& sc) { useSonClass(sc); },
sc
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.