[英]How to initialize std::array member in constructor initialization list when the size of the array is a template parameter
In the following example, I need to initialize the std::array in the A::A(H h) constructor initializer list (because class H doesn't have a default constructor), but I can't do it with an initializer list since the array size is a template parameter.在以下示例中,我需要在 A::A(H h) 构造函数初始化程序列表中初始化 std::array (因为 class H 没有默认构造函数),但我不能使用初始化程序来完成列表,因为数组大小是模板参数。
Is there a way around this?有没有解决的办法?
#include <array>
using namespace std;
struct Hash {
const vector<int> &data;
Hash(const vector<int> &data)
: data(data) {
}
uint64_t operator()(int id) const {
return data[id];
}
};
template <class H, size_t N>
class A {
public:
A(H h) {
}
std::array<H, N> hashes;
};
int main () {
vector<int> data{1, 2, 3, 4};
A<Hash, 4> a{Hash(data)};
}
std::index_sequence
was provided in order to simplify the metaprogramming task of creating and expanding a pack whose size is not fixed.提供
std::index_sequence
是为了简化创建和扩展大小不固定的包的元编程任务。 Use std::make_index_sequence
and delegate the construction to some private constructor that deduces the pack:使用
std::make_index_sequence
并将构造委托给一些推断包的私有构造函数:
A(H h) : A(h, std::make_index_sequence<N>{}) {}
template <std::size_t... i>
A(H h, std::index_sequence<i...>) : hashes{((void)i, h)...} {}
Here, ((void)i, h)
is a comma expression that evaluates to h
, but since we mentioned the pack i
inside it, it's eligible to be expanded using ...
.这里,
((void)i, h)
是一个逗号表达式,计算结果为h
,但由于我们在其中提到了包i
,因此可以使用...
对其进行扩展。 The result is N
copies of h
(one for each element of i
).结果是
h
的N
个副本( i
的每个元素一个)。 This expansion occurs inside a braced-init-list, so the result is a braced-init-list contaning N
copies of h
, which will then initialize the hashes
member.这种扩展发生在一个花括号初始化列表中,因此结果是一个包含
N
个h
副本的花括号初始化列表,然后它将初始化hashes
成员。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.