具有不同模板类型的子类的多态性
Posted
技术标签:
【中文标题】具有不同模板类型的子类的多态性【英文标题】:polymorphism with sub-classes of different template type 【发布时间】:2019-02-04 12:26:04 【问题描述】:我有带模板的类,一些类继承自他。 我们想创建父类的实例而不声明其模板类型,并调用返回模板类型的函数。
例子:
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.
【问题讨论】:
FatherClass* ch
无效,因为在显示的示例中没有这样的类FatherClass
。它是一个类的模板(FatherClass<int>
是一个类)。
请阅读xy problem 并尝试告诉我们您真正想要实现的目标。您的要求是不可能的,但也许我们可以帮助您解决您实际尝试解决的问题
你的小修改完全改变了代码的含义......我希望你不是在编造这个......
对不起,但在编辑之后,问题的含义就更不清楚了。而不是T
,而是使用int
,因为SonClass1::getValue
返回一个int
。 (ch->getValue
应该是ch->getValue()
,不是吗?)
为什么“不知道类型”?在您的示例中,您确实知道类型,并且通常当您必须知道类型时,它并不是真正的多态......
【参考方案1】:
假设你有:
未参数化(无模板)基类B
一个中间模板类I<T>
继承自B
一些派生类D1
、D2
等,每一个都继承自I
的特化
您想根据B
编写一些代码。你可以这样做——但你必须限制自己使用B
定义的API。 B
的方法可以是虚拟的,I<T>
和 Dx
中这些方法的实现/覆盖可以使用 T
类型,但这些类型不能暴露给只知道 @ 的组件987654333@.
如果您想编写一些使用T
的逻辑,那么该逻辑需要在I<T>
的方法中,或者在本身使用类类型参数化的模板函数中:
template<class U>
U someTypeSpecificLogic(I<U> intermediate)
// can call methods that accept/return U here
您不能根据 B
编写依赖于类型 T
的逻辑,因为该类型仅针对子类 I<T>
定义。考虑到您的B
是B
的不同 子类,而根本不是I<T>
。
【讨论】:
【参考方案2】:您可以完全跳过 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;
;
或者,您可以对任何使用 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);
如果你想包含它,只需使用一个变体:
int main()
std::variant<SonClass1, SonClass2> sc = SonClass2;
std::visit(
[](auto& sc) useSonClass(sc); ,
sc
);
【讨论】:
以上是关于具有不同模板类型的子类的多态性的主要内容,如果未能解决你的问题,请参考以下文章