从另一个 constexpr std::array 初始化没有默认构造函数的对象的 std::array
intializing a std::array of objects that don't have default constructor from another constexpr std::array
是否可以初始化一个对象数组,其成员是从另一个普通对象的 constexpr 数组初始化的。例如我有以下
struct X
{
X(int y): _x(y){}
int _x;
};
struct Z
{
static constexpr std::array<int, 4> arr = {1,6,0,4};
// How does one implement make_array below that constructs
// X[0] from arr[0], X[1] from arr[1], etc.
// Is it even feasible in C++14/17?
std::array<X, arr.size()> xArr = make_array( );
};
与std::index_sequence
:
template <typename T, typename U, std::size_t N, std::size_t ... Is>
constexpr std::array<T, N> make_array(const std::array<U, N>& a, std::index_sequence<Is...>)
{
return {{T(a[Is])...}};
}
template <typename T, typename U, std::size_t N>
constexpr std::array<T, N> make_array(const std::array<U, N>& a)
{
return make_array<T>(a, std::make_index_sequence<N>());
}
用法:
static constexpr std::array<int, 4> arr = {1,6,0,4};
/*constexpr*/ std::array<X, arr.size()> xArr = make_array<X>(arr);
一种解决方案是使用参数包并将其展开以构造数组的初始化列表。
我使用 std::index_sequence
和 std::make_index_sequence
构造一个参数包,其中包含元素的索引(只是 0、1、2、...、N-1),然后我解压这些索引到初始化列表中:
#include <array>
#include <utility>
// O : output type; type to convert elements to
// T : input type
// N : number of elements
// I : parameter pack of indexes
template<class O, class T, std::size_t N, std::size_t ... I>
auto make_array_impl(const std::array<T, N> & p_input, std::index_sequence<I...>) -> std::array<O, N>
{
// Unpack the parameter pack into an initializer list
// Constructs an `O` from each element in order
return {O{p_input[I]}...};
}
// O : output type; type to convert elements to
// T : input type
// N : number of elements
template<class O, class T, std::size_t N>
auto make_array(const std::array<T, N> & p_input)
{
// Helper function to automatically generate the parameter pack
return make_array_impl<O>(p_input, std::make_index_sequence<N>{});
}
是否可以初始化一个对象数组,其成员是从另一个普通对象的 constexpr 数组初始化的。例如我有以下
struct X
{
X(int y): _x(y){}
int _x;
};
struct Z
{
static constexpr std::array<int, 4> arr = {1,6,0,4};
// How does one implement make_array below that constructs
// X[0] from arr[0], X[1] from arr[1], etc.
// Is it even feasible in C++14/17?
std::array<X, arr.size()> xArr = make_array( );
};
与std::index_sequence
:
template <typename T, typename U, std::size_t N, std::size_t ... Is>
constexpr std::array<T, N> make_array(const std::array<U, N>& a, std::index_sequence<Is...>)
{
return {{T(a[Is])...}};
}
template <typename T, typename U, std::size_t N>
constexpr std::array<T, N> make_array(const std::array<U, N>& a)
{
return make_array<T>(a, std::make_index_sequence<N>());
}
用法:
static constexpr std::array<int, 4> arr = {1,6,0,4};
/*constexpr*/ std::array<X, arr.size()> xArr = make_array<X>(arr);
一种解决方案是使用参数包并将其展开以构造数组的初始化列表。
我使用 std::index_sequence
和 std::make_index_sequence
构造一个参数包,其中包含元素的索引(只是 0、1、2、...、N-1),然后我解压这些索引到初始化列表中:
#include <array>
#include <utility>
// O : output type; type to convert elements to
// T : input type
// N : number of elements
// I : parameter pack of indexes
template<class O, class T, std::size_t N, std::size_t ... I>
auto make_array_impl(const std::array<T, N> & p_input, std::index_sequence<I...>) -> std::array<O, N>
{
// Unpack the parameter pack into an initializer list
// Constructs an `O` from each element in order
return {O{p_input[I]}...};
}
// O : output type; type to convert elements to
// T : input type
// N : number of elements
template<class O, class T, std::size_t N>
auto make_array(const std::array<T, N> & p_input)
{
// Helper function to automatically generate the parameter pack
return make_array_impl<O>(p_input, std::make_index_sequence<N>{});
}