C++17 遍历参数包的一个子集
C++17 Iterate over a subset of parameter pack
我有一个接收参数包的结构。假设参数包的大小永远不会小于 3。此外,应该在编译时评估结构中找到的 std::array
。我想用参数包填充数组,但是我想跳过第一个和最后一个元素
这是我的代码:
#include <iostream>
#include <array>
#include <cstdint>
template<int32_t ...Ts>
struct St {
const std::array<int32_t, sizeof...(Ts)-2U> arr{};
};
int main() {
constexpr St<7, 2, 1, 5, 6> s;
std::cout << s.arr[2] << std::endl;
return 0;
}
理想情况下,我想将 std::index_sequence
与 [1, sizeof_parameter_pack - 1] 或 [0, size_of_parameter_pack - 2] 中的元素和折叠表达式一起使用填充数组。但是,我正在努力创建 index_sequence。我不希望该结构接收另一个模板参数。我怎样才能做到这一点?
我认为最简单的方法是执行以下操作:
#include <iostream>
#include <array>
#include <cstdint>
template<uint32_t... Ts>
constexpr std::array<int32_t, sizeof...(Ts)-1> create_arr() {
const std::array<int32_t, sizeof...(Ts)> tmp{Ts...};
std::array<int32_t, sizeof...(Ts)-1> ret{};
// With C++20, this is a call to std::copy
for(auto i = 0ul; i != tmp.size()-1; ++i) {
ret[i] = tmp[i];
}
return ret;
}
template<uint32_t first, uint32_t ...Ts>
struct St {
const std::array<int32_t, sizeof...(Ts)-1> arr = create_arr<Ts...>();
};
int main() {
constexpr St<7U, 2U, 1U, 5U, 6U> s;
std::cout << s.arr[2] << std::endl;
return 0;
}
这可以在 运行 时进行评估(如果您的 St
对象不是 constexpr
),您可以通过声明数组成员 constexpr
.
顺便说一句:您确定要从 uint32_t
初始化 int32_t
数组吗?
可能的解决方案std::index_sequence
:
template<int32_t... Ts>
struct St {
static constexpr auto Size = sizeof...(Ts) - 2;
const std::array<int32_t, Size> arr;
constexpr St() : St(std::array{Ts...}, std::make_index_sequence<Size>{}) {}
private:
template<class Arr, std::size_t... I>
constexpr St(Arr init, std::index_sequence<is...>) : arr{init[I + 1]...} {}
};
我有一个接收参数包的结构。假设参数包的大小永远不会小于 3。此外,应该在编译时评估结构中找到的 std::array
。我想用参数包填充数组,但是我想跳过第一个和最后一个元素
这是我的代码:
#include <iostream>
#include <array>
#include <cstdint>
template<int32_t ...Ts>
struct St {
const std::array<int32_t, sizeof...(Ts)-2U> arr{};
};
int main() {
constexpr St<7, 2, 1, 5, 6> s;
std::cout << s.arr[2] << std::endl;
return 0;
}
理想情况下,我想将 std::index_sequence
与 [1, sizeof_parameter_pack - 1] 或 [0, size_of_parameter_pack - 2] 中的元素和折叠表达式一起使用填充数组。但是,我正在努力创建 index_sequence。我不希望该结构接收另一个模板参数。我怎样才能做到这一点?
我认为最简单的方法是执行以下操作:
#include <iostream>
#include <array>
#include <cstdint>
template<uint32_t... Ts>
constexpr std::array<int32_t, sizeof...(Ts)-1> create_arr() {
const std::array<int32_t, sizeof...(Ts)> tmp{Ts...};
std::array<int32_t, sizeof...(Ts)-1> ret{};
// With C++20, this is a call to std::copy
for(auto i = 0ul; i != tmp.size()-1; ++i) {
ret[i] = tmp[i];
}
return ret;
}
template<uint32_t first, uint32_t ...Ts>
struct St {
const std::array<int32_t, sizeof...(Ts)-1> arr = create_arr<Ts...>();
};
int main() {
constexpr St<7U, 2U, 1U, 5U, 6U> s;
std::cout << s.arr[2] << std::endl;
return 0;
}
这可以在 运行 时进行评估(如果您的 St
对象不是 constexpr
),您可以通过声明数组成员 constexpr
.
顺便说一句:您确定要从 uint32_t
初始化 int32_t
数组吗?
可能的解决方案std::index_sequence
:
template<int32_t... Ts>
struct St {
static constexpr auto Size = sizeof...(Ts) - 2;
const std::array<int32_t, Size> arr;
constexpr St() : St(std::array{Ts...}, std::make_index_sequence<Size>{}) {}
private:
template<class Arr, std::size_t... I>
constexpr St(Arr init, std::index_sequence<is...>) : arr{init[I + 1]...} {}
};