(我不知道如何命名这个问题,也找不到类似的内容。抱歉,如果这是重复的)
如果我想继承某个基模板类,我可以这样做:
template<typename A=int, typename B=char> class C {};
template<typename... Args> class D : public C<Args...> {}; //it works!
这样我就可以在项目中更改传递给模板类 C 的参数,而不必更改类 D 的每个用法。太棒了。但是,如果我的模板类不仅使用类型作为参数,而且还使用值呢?例如:
template<int dim=3, typename float_t=double> class GeometricObject{};
template<typename... Args> class Point : public GeometricObject<Args...>{}; //it doesnt work
当然,我可以在开头定义最后一个带有整数类型的模板。但这不是一种方法,如果我有 100 个不同的类都继承自 GeometricObject,然后我将默认的 dim
值更改为 2,我就必须更改每个类的定义。
我也希望有一种方法可以不使用任何#define
、#else
和类似的预处理器命令。我知道模板实际上也是预处理器命令,但是......好吧,让我们在这里变得现代;)
最佳答案
您不能在模板参数包中混合类型和非类型参数。但似乎你的Point
而其他派生类则不需要单独访问参数包实参。在这种情况下,传递基类更容易,并且语义上更正确:
template<int dim=3, typename float_t=double> class GeometricObject{};
template<class GeometricObject=GeometricObject<>> class Point : public GeometricObject{};
实例化 Point
那么可能看起来像:
Point<> a{}; // the same as Point<GeometricObject<>> a{};
Point<GeometricObject<4>> b{};
Point<GeometricObject<2, float>> c{};
当然是GeometricObject<...>
可以将类型定义为更短的内容。此外,它可以看起来像一个命名空间,而不是分别为每个几何对象提供参数:
template<int dim = 3, typename float_t = double>
struct GeometricObjects {
using Base = GeometricObject<dim, float_t>;
using Point = ::Point<Base>;
// ...
};
using TwoDim = GeometricObjects<2>;
TwoDim::Point a{};
关于c++11 - C++ : template class inheritance with variable-type parameters using parameter packs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41223873/