C++ 使用构造函数参数初始化成员数组
C++ Initialize Member Array with Constructor Argument
我有一个模板 class,其中包含一个编译时常量长度的成员数组。我希望这个数组是常量,但事实证明根据构造函数提供的输入初始化它很困难:
struct Input {
int value;
};
template<size_t Size>
struct Foo {
int const myVals[Size];
Foo(std::array<Input, Size> const &in)
: myVals{ in[0].value, in[1].value, /* How many times? */ } {
}
}
因为我不知道数组的大小,所以我不知道要初始化多少个值myVals
。以下代码有效,但我质疑它是否是最佳方法:
template<size_t Size>
struct Foo {
std::array<int, Size> const myVals;
Foo(std::array<Input, Size> const &in)
: myVals{ toIntArray(in) } {
}
private:
static std::array<int, Size> toIntArray(std::array<Input, Size> const &in) {
std::array<int, Size> result;
for (size_t i{ 0 }; i < Size; ++i) {
result[i] = in[i].value;
}
return result;
}
}
是否有更简洁或更普遍接受的方式来填充常量成员数组的值?
您可以使用std::index_sequence
获取数组的索引作为non-type模板参数包。然后就可以使用参数包扩展了。
template<size_t Size>
struct Foo {
int const myVals[Size];
Foo(std::array<Input, Size> const &in)
: Foo(in, std::make_index_sequence<Size>()) { }
private:
template<size_t... Is>
Foo(std::array<Input, Size> const &in, std::index_sequence<Is...>)
: myVals{in[Is].value...} { }
}
使用带有 size_t... Is
包和 std::index_sequence<Is...>
参数的辅助模板是处理 fixed-size 可索引容器的常见模式。 index_sequence
实际上什么也没做;它只是一个代理,因此可以推导出 Is
模板参数。例如。如果你 check on Godbolt 它似乎在 -O1
下完全消失了。
我有一个模板 class,其中包含一个编译时常量长度的成员数组。我希望这个数组是常量,但事实证明根据构造函数提供的输入初始化它很困难:
struct Input {
int value;
};
template<size_t Size>
struct Foo {
int const myVals[Size];
Foo(std::array<Input, Size> const &in)
: myVals{ in[0].value, in[1].value, /* How many times? */ } {
}
}
因为我不知道数组的大小,所以我不知道要初始化多少个值myVals
。以下代码有效,但我质疑它是否是最佳方法:
template<size_t Size>
struct Foo {
std::array<int, Size> const myVals;
Foo(std::array<Input, Size> const &in)
: myVals{ toIntArray(in) } {
}
private:
static std::array<int, Size> toIntArray(std::array<Input, Size> const &in) {
std::array<int, Size> result;
for (size_t i{ 0 }; i < Size; ++i) {
result[i] = in[i].value;
}
return result;
}
}
是否有更简洁或更普遍接受的方式来填充常量成员数组的值?
您可以使用std::index_sequence
获取数组的索引作为non-type模板参数包。然后就可以使用参数包扩展了。
template<size_t Size>
struct Foo {
int const myVals[Size];
Foo(std::array<Input, Size> const &in)
: Foo(in, std::make_index_sequence<Size>()) { }
private:
template<size_t... Is>
Foo(std::array<Input, Size> const &in, std::index_sequence<Is...>)
: myVals{in[Is].value...} { }
}
使用带有 size_t... Is
包和 std::index_sequence<Is...>
参数的辅助模板是处理 fixed-size 可索引容器的常见模式。 index_sequence
实际上什么也没做;它只是一个代理,因此可以推导出 Is
模板参数。例如。如果你 check on Godbolt 它似乎在 -O1
下完全消失了。