![](/img/trans.png)
[英]Project A rely on shared library B, B rely on C, A don't rely on C. When I use an API of B, warning B can't find C
[英]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.