[英]polymorphism with sub-classes of different template type
我有帶有模板的課程,有些課程是從他那里繼承的。 我們要創建父類的實例而不聲明其模板類型,並調用一個返回模板類型的函數。
例:
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.
}
假設您有:
B
B
繼承的中間模板類I<T>
D1
, D2
等,每個都繼承自I
的專業化 您想根據B
編寫一些代碼。 您可以做到這一點-但您必須限制自己使用B
定義的API。 B
的方法可以是虛擬的,並且I<T>
和Dx
中這些方法的實現/重寫可以使用類型T
,但那些類型不能暴露給僅了解B
的組件。
如果要編寫一些使用T
邏輯,則該邏輯必須在I<T>
的方法中,或者在本身使用類類型參數化的模板函數中:
template<class U>
U someTypeSpecificLogic(I<U> intermediate) {
// can call methods that accept/return U here
}
您不能使用依賴於類型T
的B
來編寫邏輯,因為該類型僅為子類I<T>
定義。 認為B
你是一個不同的子類, B
,而不是I<T>
在所有。
您可以完全跳過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
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.