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
I<T>
inheriting from B
D1
, D2
, etc. each of which inherits from a specialization of I
You want to write some code in terms of B
. You can do that--but you have to limit yourself to using the API that B
defines. 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
.
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:
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>
. Consider that the B
you have be a different subclass of B
and not an I<T>
at all.
You could skip the FatherWrap
entirely and make the base class return a variant:
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
:
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
);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.