我有带有模板的课程,有些课程是从他那里继承的。 我们要创建父类的实例而不声明其模板类型,然后调用一个返回模板类型的函数。
示例:
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.
}
答案 0 :(得分:3)
假设您拥有:
B
I<T>
继承的中间模板类B
D1
,D2
等,每个类都继承自I
的专业化您想用B
来编写一些代码。您可以做到这一点-但您必须限制自己使用B
定义的API。 B
的方法可以是虚拟的,I<T>
和Dx
中这些方法的实现/覆盖可以使用类型T
,但是这些类型不能公开唯一了解B
的组件。
如果您想编写一些使用T
的逻辑,则该逻辑必须在I<T>
的方法中,或者在本身使用类类型进行参数化的模板函数中: / p>
template<class U>
U someTypeSpecificLogic(I<U> intermediate) {
// can call methods that accept/return U here
}
您不能使用取决于类型B
的{{1}}来编写逻辑,因为该类型仅是为子类T
定义的。考虑到I<T>
是B
的不同子类,而根本不是B
。
答案 1 :(得分:0)
您可以完全跳过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
);
}