繁体   English   中英

如何解读A <b<t> >* 作为一个<c<t> >* 其中 B:公共 C<t> ? </t></c<t></b<t>

[英]How to interpret A<B<T>>* as A<C<T>>* where B : public C<T>?

考虑一个包含以下代码的文件 main.cc:

template<typename Commodity>
class Shop
{
public:
    Shop(){}
    ~Shop(){}
};

template<typename FuelType>
class Car
{
public:
    Car(){}
    virtual ~Car(){}
};

template<typename FuelType>
class Volkswagen : public Car<FuelType>
{
public:
    Volkswagen(){}
    ~Volkswagen(){}
};

int main()
{   
    // this is fine...
    Car<int>* myCar = new Volkswagen<int>();

    delete myCar;

    // ...but this isn't
    Shop<Car<int>>* myCarShop = new Shop<Volkswagen<int>>();

    return 0;
}

当我尝试编译时,出现错误:

cannot convert 'Shop<Volkswagen<int> >*' to 'Shop<Car<int> >*' in initialization...'

现在,我明白了为什么会出现此错误。 这是因为Shop<Volkswagen<T>>通常不必继承自Shop<Car<T>>

我的问题是:如何实现这样的结构? 是否有更好的类和模板方法,或者当我完全确定Shop<Volkswagen<T>>始终是Shop<Car<T>>时,我应该尝试明确地转换指针吗?

编辑 1:一种解决方案是添加 class

template<typename FuelType>
class VolkswagenShop : public Shop<Volkswagen<FuelType>>, public virtual Shop<Car<FuelType>>
{
public:
  VolkswagenShop(){}
  ~VolkswagenShop(){}
};

然后写

Shop<Car<int>>* myCarShop = new VolkswagenShop<int>();

这编译,但结构已经变得复杂到我,以我非常有限的 c++ 能力,我不确定这是否会导致任何问题。

那么,冒着过于模糊的风险,上述解决方案会导致任何明显的问题吗?

模板实例化不是继承! foo<A>foo<B>是两种截然不同且不相关的类型。 如果您希望所有Shop<CARTYPE<T>>都继承自Shop<Car<T>> ,那么您可以这样做。

如果可以将Shop的声明更改为采用 2 个模板参数(如果您不害怕模板模板参数),您可以这样做:

template<typename FuelType>
class Car
{
public:
    Car(){}
    virtual ~Car(){}
};

template<typename FuelType>
class Volkswagen : public Car<FuelType>
{
public:
    Volkswagen(){}
    ~Volkswagen(){}
};

template <template<class> class CarType,typename Commodity>
class Shop : public Shop<Car,Commodity>
{
public:
    using Car_t = CarType<Commodity>;
    Shop(){}
    virtual ~Shop(){}
};

template <typename Commodity>
class Shop<Car,Commodity> {
    virtual ~Shop(){}
};


int main()
{   
    // this is fine...
    Car<int>* myCar = new Volkswagen<int>();
    delete myCar;
    // this also
    Shop<Car,int>* myCarShop = new Shop<Volkswagen,int>();
    delete myCarShop;
    return 0;
}

然而,模板专业化也不是继承! 您将需要重复通用模板和template <typename Commodity> class Shop<Car,Commodity> {}; 专业化。 为避免代码重复,您可以编写一个不是模板的ShopBase class,并提供您希望在所有商店中多态使用的界面。

PS:混合编译时和运行时多态是可能的,但我会重新考虑你真正需要什么。 看看CRTP可能会给您一些启发。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM