如何在类模板的成员初始化列表中初始化数组类型的数据成员?

问题描述 投票:0回答:1

例如,我有一个名为

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。

c++ arrays c++14 member-initialization index-sequence
1个回答
2
投票

正如你所说,如果知道尺寸,你可以直接写

value_{v[0], v[1], v[2]}

解决方案A -
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
创建索引序列时指定的那样。

解决方案 B - 聚合初始化

但是,由于您的

Vector
类仅包含一个数组成员,因此没有构造函数并依赖聚合初始化会更容易。 如果你没有构造函数,你也可以写
Vector<3>{1, 2, 3}

解决方案C -
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的,但是那里的解决方案也适用于旧版本。

© www.soinside.com 2019 - 2024. All rights reserved.