我想创建一个像这样的通用 Vector 类 Vector<int Dimension, typename Type>
。这是我的代码:
template <int Dimension, typename Type>
class Vector
{
public:
Vector()
: _data {}
{}
Vector(const std::array<Type, Dimension>& init)
: _data {init}
{}
...
protected:
std::array<Type, Dimension> _data;
};
通过该声明,我可以使用 std::array
初始化我的向量.
Vector<3, float> vec({1.0f, 2.0f, 3.0f});
// or like this
Vector<3, float> vec = {{1.0f, 2.0f, 3.0f}};
但现在我希望我的向量有一个更好的构造函数来处理一些常见的向量类型,如 Vec1、Vec2、Vec3,... 我尝试创建一个递归模板类来为每个模板添加一个额外的构造函数:
template <typename Type>
class Vector<3, Type>
{
public:
Vector(const Type& x, const Type& y, const Type& z)
: _data {x, y, z}
{}
};
但是当我编译我的程序时,我收到了这个错误:
error C3861: '_data': identifier not found
我的问题是:
- 为什么会发生此错误?
- 我如何为我的
Vector
的一些通用模板添加额外的构造函数.
PS:抱歉,如果我的英语很难理解🤦♀️。
最佳答案
为什么?
这里没有递归。 Vector<3, Type>
是一个完全独立的东西,与通用的Vector<Dimension, Type>
无关。 。它不包含任何_data
或主模板包含的任何其他内容。
如何?
这里不需要递归或专门化,您需要一个转发构造函数。
template <int Dimension, typename Type>
class Vector
{
public:
template <typename ... T>
Vector(T&& ... t)
: _data{std::forward<T>(t)...} {}
protected:
std::array<Type, Dimension> _data;
};
这是您需要的唯一构造函数。它基本上是说“用任何你可以初始化_data的东西来初始化Vector”。所以你可以:
Vector<4, int> v4(1,2,3,4);
Vector<2, int> v2{1,2};
std::array<float, 3> u3 = {1.0, 2.0, 3.0};
Vector<3, float> v3{u3};
Vector<5, float> v5;
这就是全部吗?
没有。也许您确实需要向 Vector<3,Type>
添加一些功能主模板中不存在。在这种情况下,您可以使用继承。
重命名您的
Vector
类模板为VectorBase
创建一个新的
Vector
继承自“VectorBase”并使用其构造函数的类模板,仅此而已:template <int Dimension, typename Type> class Vector : public VectorBase<Dimension, Type> { public: using VectorBase<Dimension, Type>::VectorBase; };
现在您可以专注于
Vector
并向其添加功能。您需要重复using
每个专业都有声明,但这并不是太多的样板。
关于templates - C++ 模板类专门化构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73583586/