例如,我有一个名为
Vector
的类,表示向量,还有一个名为 Integer
的类,表示整数。
class Integer{
public:
Integer(int v):value_(v){};
private:
int value_;
};
template<uint32_t Dim>
class Vector{
public:
Vector(int v[Dim])
://How to initialize each element of the value_ array here?
{
}
private:
Integer value_[Dim];
}
由于
Integer
没有默认构造函数,因此必须在 value_
的成员初始值设定项列表中初始化 Vector
数组的每个元素。但是,由于数组的长度是模板参数,所以不能直接使用value_{v[0], v[1], v[2]}
之类的东西来初始化value_数组。
我正在使用 c++14。
正如你所说,如果知道尺寸,你可以直接写
value_{v[0], v[1], v[2]}
。
std::index_sequence
鉴于尺寸未知,您可以这样写:
private:
template <std::size_t... I>
Vector(const int(&v)[N], std::index_sequence<I...>)
: value_{v[I]...} {}
public:
Vector(const int(&v)[Dims])
: Vector(v, std::make_index_sequence<Dims>{}) {}
注意:这使用对数组的引用,以便检查大小。
包扩展
v[I]...
的作用类似于 v[0], v[1], ...
,用于任意数量的 Dims
索引(如使用 std::make_index_sequence
创建索引序列时指定的那样。
但是,由于您的
Vector
类仅包含一个数组成员,因此没有构造函数并依赖聚合初始化会更容易。
如果你没有构造函数,你也可以写 Vector<3>{1, 2, 3}
。
std::array
你也可以有一个构造函数:
// note: value_ should be std::array as well
Vector(const std::array<int, Dims>& content) : value_{content} {}
std::array
具有值语义,并且使问题变得微不足道,因为您可以像任何其他对象一样复制/移动它。
参见 从固定大小的 std::span 创建固定大小的 std::array 的惯用方法是什么?。这个问题是关于C++20的,但是那里的解决方案也适用于旧版本。