简体   繁体   English

具有不同模板类型的子类的多态性

[英]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: 假设您有:

  • An unparameterized (no template) base class B 非参数化(无模板)基本类B
  • An intermediate template class I<T> inheriting from B B继承的中间模板类I<T>
  • Some derived classes D1 , D2 , etc. each of which inherits from a specialization of I 一些派生类D1D2等,每个都继承自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> . 您不能使用依赖于类型TB来编写逻辑,因为该类型仅为子类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.

相关问题 使用好奇递归模板模式在子类之间进行转换 - Conversion between sub-classes using Curiously Recursive Template Pattern 子类,赋值运算符重载? - Sub-classes, assignment operator overloading? 状态机,子类和功能指针 - State Machines, Sub-Classes, and Function Pointers C++中子类的架构 - Architecture of sub-classes in C++ 如何创建使用 CreateDefaultSubobject() 但允许子类更改子对象类型的 UE4 UCLASS 基础 class? - How can I create a UE4 UCLASS base class that uses CreateDefaultSubobject() but allow sub-classes to change the type of the sub-object? 将可变参数类模板的子类传递给仅接受基类的函数(通过参数包推导/推断) - Passing variadic class template's sub-classes to function that only accepts the base class (via parameter pack deduction/inference) 实例化子类的多态问题 - Polymorphism issue with instantiating sub classes C++ - 如何在析构函数中删除子类 - C++ - how to delete sub-classes in destructor 子类是否真的继承了私有成员变量? - Do Sub-Classes Really Inherit Private Member Variables? 访问保护的变量-具有继承和子类的复杂情况 - access protected variable - complicated situation with inheritance and sub-classes
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM