Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基类中编译时派生模板类的大小_C++_Templates_Polymorphism - Fatal编程技术网

C++ 基类中编译时派生模板类的大小

C++ 基类中编译时派生模板类的大小,c++,templates,polymorphism,C++,Templates,Polymorphism,我有一个现有的体系结构,它使用多态容器来保存派生模板类的实例。现在我需要重写基类中的一个运算符,并在编译时用派生类的大小声明一个类型。 该体系结构如下图所示: 我已经在基类头中尝试了模板类的前向声明,但没有成功。我还尝试用基类制作一个模板来获取类类型,但这对多态容器不起作用 提前感谢您的设计存在的问题是,模型类无法知道其派生类的大小,如果它不知道是哪个类派生它。 正如您正确指出的,将模型本身作为类模板将阻止您创建模型的动态容器 为了解决这个问题,您可以添加一层静态多态性(也称为CRTP)来实现

我有一个现有的体系结构,它使用多态容器来保存派生模板类的实例。现在我需要重写基类中的一个运算符,并在编译时用派生类的大小声明一个类型。
该体系结构如下图所示:

我已经在基类头中尝试了模板类的前向声明,但没有成功。我还尝试用基类制作一个模板来获取类类型,但这对多态容器不起作用


提前感谢

您的设计存在的问题是,
模型
类无法知道其派生类的大小,如果它不知道是哪个类派生它。 正如您正确指出的,将
模型
本身作为类模板将阻止您创建
模型
的动态容器

为了解决这个问题,您可以添加一层静态多态性(也称为CRTP)来实现您想要的

其思想是从模板基类
ModelCRTPBase
派生
Model
,然后将接口功能委托给实际实现

显然,知道其子级大小的仍然不是
Model
类,而是
ModelCRTPBase
。但是由于
模型
仅用作多态接口类,并且模型的所有常见功能都在
ModelCRTPBase
中(它在编译时知道大小),这应该不是问题

#include <iostream>
#include <vector>
#include <memory>


class Model {

public:
    virtual ~Model() {}
    virtual void print() = 0;
};

template<typename Derived>
class ModelCRTPBase : public Model {

    Derived& derived() {
        return static_cast<Derived&>(*this);
    }

public:

    static size_t  size() {
        return sizeof(Derived);
    }

    void print() override  {
        std::cout << "print Base, size = " << size() << '\n';
        derived().print_impl();
    }

};

template <typename T>
class ModelA : public ModelCRTPBase<ModelA<T>> {

public:

    void print_impl() {
        std::cout << "ModelA<" << typeid(T{}).name() << ">\n";
    }
};

template <typename T>
class ModelB : public ModelCRTPBase<ModelB<T>> {

    int payload;

public:

    void print_impl() {
        std::cout << "ModelB<" << typeid(T{}).name() << ">\n";
    }
};
int main() {

    std::vector<std::shared_ptr<Model>> vec;
    vec.push_back(std::make_shared<ModelA<int>>());
    vec.push_back(std::make_shared<ModelB<float>>());

    vec[0]->print();
    vec[1]->print();

}
#包括
#包括
#包括
类模型{
公众:
虚拟~Model(){}
虚空打印()=0;
};
样板
类ModelCRTPBase:公共模型{
派生&Derived(){
返回静态_cast(*此);
}
公众:
静态大小\u t大小(){
返回sizeof(派生);
}
void print()覆盖{

std::cout似乎您有一个设计问题。您需要
模型的所有可能选项
?即使是在这个阶段您不知道的选项?当继承类知道其继承类时,就已经存在设计问题,而模板类的设计问题似乎最糟糕。为什么您需要在编译时而不是在执行时知道大小按时(
virtual size\t sizeOf()const=0;
on Model并在ModelA和ModelB上实现)似乎在这背后有一个有趣的问题,但并不清楚。我知道体系结构更糟糕,但它是给定的。我需要在编译时使用它,因为我需要在重写的运算符中使用模板类。
print Base, size = 8
ModelA<i>
print Base, size = 16
ModelB<f>