我尝试制作一个通用但仍然高效的多维Point
类。
我所拥有的是Dimensions
enum
enum Dimension : std::size_t { _2D = 2, _3D = 3 };
Point
class
template <typename T, Dimension D>
class Point : public std::array<T, D>
{
public:
T& at(size_t idx) { return std::array<T,D>::at(idx); };
const T& at(size_t idx) const { return std::array<T,D>::at(idx); };
Dimension dim() const { return D; }
...
};
我想创建nices构造函数,所以我添加了(在我的类定义之外)
template <typename T>
Point<T,_2D>::Point(T x, T y) { at(0) = x; at(1) = y; }
template <typename T>
Point<T,_3D>::Point(T x, T y, T z) { at(0) = x; at(1) = y; at(2) = z; }
但我仍然无法使用。编译器告诉我只注册了默认(空)和复制构造函数。
如何定义参数列表长度取决于我的Dimension
模板的构造函数?
答案 0 :(得分:1)
我会这样做,因为我懒得写同一件事的许多版本:
template<class T, Dimension D>
class Point : public std::array<T,D> {
template<class... Args>
Point(Args... vs) :
std::array<T,D>{{vs...}}
{
static_assert(sizeof...(Args) == D, "wrong number of args");
}
...
};
答案 1 :(得分:0)
有几种方法可以实现这一目标。在您的情况下,使用std::enable_if
:
template <typename T, Dimension D>
class Point : public std::array<T, D>
{
public:
template <
Dimension D2=D,
typename = typename std::enable_if<D2==_2D>::type
>
Point(T x,T y);
template <
Dimension D2=D,
typename = typename std::enable_if<D2==_3D>::type
>
Point(T x,T y,T z);
T& at(size_t idx) { return std::array<T,D>::at(idx); };
const T& at(size_t idx) const { return std::array<T,D>::at(idx); };
Dimension dim() const { return D; }
...
};
另一种选择是将其分解为多个类并使用专门化:
template <typename T, Dimension D>
class PointBase : public std::array<T, D>
{
public:
T& at(size_t idx) { return std::array<T,D>::at(idx); };
const T& at(size_t idx) const { return std::array<T,D>::at(idx); };
Dimension dim() const { return D; }
...
};
template <typename T, Dimension D> class Point;
template <typename T>
class Point<T,_2D> : public PointBase<T,_2D> {
public:
Point(T x,T y);
};
template <typename T>
class Point<T,_3D> : public PointBase<T,_3D> {
public:
Point(T x,T y,T z);
};