模板特定的构造函数
Template specific constructor
我正在编写自己的向量 class,但我遇到了问题。
我将我的 class 定义为模板,我对每个向量大小都有定义,并且我想要每个向量大小的特定构造函数。
这是代码:
template<int size>
ref class Vector
{
internal:
Vector(int _x, int _y, int _z, int _w);
private:
float *m_data = new float[4];
};
定义是:
using Vector2 = Vector<2>;
using Vector3 = Vector<3>;
using Vector4 = Vector<4>;
首先我可以这样做吗?如果答案是肯定的怎么办?
如果你真的想要每个模板实例有不同的行为,你可以这样做:
//specific version for when 0 is passed as the template argument
template<>
Vector<0>::Vector (int _x, int _y, int _z, int _w)
{
//some Vector<0> related stuff
}
//Vector<1> will use the default version
//specific version for when 2 is passed as the template argument
template<>
Vector<2>::Vector (int _x, int _y, int _z, int _w)
{
//some Vector<2> related stuff
}
如果您想要通用接口,请将构造函数定义为具有 4 个参数并对其进行特殊化。在内部,仅初始化那些对这种大小的向量有效的成员:
template <>
Vector<1>::Vector(int _x, int _y, int _z, int _w)
: x(_x) //1D vector has only 'x'
{
}
template <>
Vector<2>::Vector(int _x, int _y, int _z, int _w)
: x(_x)
, y(_y) //2D vector has 'x' and 'y'
{
}
等但这很丑陋,迫使你做一些事情 "common",例如你将持有 4
个组件,即使 2D vector
。有一些变通方法(模板结构用作成员变量,专门用于每种大小的向量),但这要复杂得多。由于不同大小的向量实际上是 不同类型 ,我会选择完全 class 专业化:
template<int size>
class Vector;
template<>
class Vector<1>
{
protected:
int x;
public:
Vector(int _x)
: x(_x)
{ }
//other members
};
template<>
class Vector<2>
{
protected:
int x, y;
public:
Vector(int _x, int _y)
: x(_x)
, y(_y)
{ }
//other members
};
那么你可以这样使用:
Vector<1> v_1(2);
Vector<2> v_2(4, 6);
//etc...
此外,第二个解决方案将允许您的向量的客户端仅针对您明确允许的那些 size
实例化它。
对于 C++11,您可以执行如下操作:
template<int size>
class Vector
{
public:
template <typename ...Ts,
typename = typename std::enable_if<size == sizeof...(Ts)>::type>
explicit Vector(Ts... args) : m_data{static_cast<float>(args)...} {}
private:
float m_data[size];
};
using Vector2 = Vector<2>;
using Vector3 = Vector<3>;
using Vector4 = Vector<4>;
int main()
{
Vector2 v2(42, 5);
Vector3 v3(42, 5, 3);
Vector4 v4(42, 5, 51, 69);
}
我正在编写自己的向量 class,但我遇到了问题。 我将我的 class 定义为模板,我对每个向量大小都有定义,并且我想要每个向量大小的特定构造函数。 这是代码:
template<int size>
ref class Vector
{
internal:
Vector(int _x, int _y, int _z, int _w);
private:
float *m_data = new float[4];
};
定义是:
using Vector2 = Vector<2>;
using Vector3 = Vector<3>;
using Vector4 = Vector<4>;
首先我可以这样做吗?如果答案是肯定的怎么办?
如果你真的想要每个模板实例有不同的行为,你可以这样做:
//specific version for when 0 is passed as the template argument
template<>
Vector<0>::Vector (int _x, int _y, int _z, int _w)
{
//some Vector<0> related stuff
}
//Vector<1> will use the default version
//specific version for when 2 is passed as the template argument
template<>
Vector<2>::Vector (int _x, int _y, int _z, int _w)
{
//some Vector<2> related stuff
}
如果您想要通用接口,请将构造函数定义为具有 4 个参数并对其进行特殊化。在内部,仅初始化那些对这种大小的向量有效的成员:
template <>
Vector<1>::Vector(int _x, int _y, int _z, int _w)
: x(_x) //1D vector has only 'x'
{
}
template <>
Vector<2>::Vector(int _x, int _y, int _z, int _w)
: x(_x)
, y(_y) //2D vector has 'x' and 'y'
{
}
等但这很丑陋,迫使你做一些事情 "common",例如你将持有 4
个组件,即使 2D vector
。有一些变通方法(模板结构用作成员变量,专门用于每种大小的向量),但这要复杂得多。由于不同大小的向量实际上是 不同类型 ,我会选择完全 class 专业化:
template<int size>
class Vector;
template<>
class Vector<1>
{
protected:
int x;
public:
Vector(int _x)
: x(_x)
{ }
//other members
};
template<>
class Vector<2>
{
protected:
int x, y;
public:
Vector(int _x, int _y)
: x(_x)
, y(_y)
{ }
//other members
};
那么你可以这样使用:
Vector<1> v_1(2);
Vector<2> v_2(4, 6);
//etc...
此外,第二个解决方案将允许您的向量的客户端仅针对您明确允许的那些 size
实例化它。
对于 C++11,您可以执行如下操作:
template<int size>
class Vector
{
public:
template <typename ...Ts,
typename = typename std::enable_if<size == sizeof...(Ts)>::type>
explicit Vector(Ts... args) : m_data{static_cast<float>(args)...} {}
private:
float m_data[size];
};
using Vector2 = Vector<2>;
using Vector3 = Vector<3>;
using Vector4 = Vector<4>;
int main()
{
Vector2 v2(42, 5);
Vector3 v3(42, 5, 3);
Vector4 v4(42, 5, 51, 69);
}