解压多个参数包以初始化二维数组
unpack multiple parameter packs to initialize a 2d array
我正在尝试解压多个参数包,以便 arr[i][j] = X(i,j)
。但是,我在下面的当前方法中遇到以下错误。是否有使用 C++14/17 实现上述目标的方法?
// Non copyable and default constructable
struct X
{
X(const X&) = delete;
X(int x, int y) : _x(x), _y(y)
{}
int _x;
int _y;
};
X getX(int i, int j)
{
return X(i,j);
}
template <std::size_t ...Xidx, std::size_t ... Yidx>
auto make_2d_array(std::index_sequence<Xidx...>, std::index_sequence<Yidx...>)
{
std::array<std::array<X,sizeof...(Xidx)>, sizeof...(Yidx)> arr = {getX(Xidx, Yidx)...};
return arr;
}
static constexpr std::size_t M = 5;
static constexpr std::size_t N = 6;
int main()
{
std::array<std::array<X,M>, N> arr = make_2d_array(std::make_index_sequence<M>{}, std::make_index_sequence<N>{});
}
错误
<source>:26:87: error: pack expansion contains parameter packs 'Xidx' and 'Yidx' that have different lengths (5 vs. 6)
std::array<std::array<X,sizeof...(Xidx)>, sizeof...(Yidx)> arr = {getX(Xidx, Yidx)...};
~~~~ ~~~~ ^
<source>:35:42: note: in instantiation of function template specialization 'make_2d_array<0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5>' requested here
std::array<std::array<X,M>, N> arr = make_2d_array(std::make_index_sequence<M>{}, std::make_index_sequence<N>{});
^
1 error generated.
Compiler returned: 1
我会这样做
template<std::size_t... XIs, std::size_t... YIs>
std::array<std::array<X, sizeof...(XIs)>, sizeof...(YIs)> make_2d_array(std::index_sequence<XIs...>, std::index_sequence<YIs...>)
{
return {
[](auto YI) -> std::array<X, sizeof...(XIs)> {
return {getX(XIs, YI)...};
}(YIs)...
};
}
是的,有点可怕。原理很简单,我们需要在语法上将 XIs
和 YIs
分开,每个 ...
扩展只解压其中一个,我们需要两个扩展来做“产品”而不是“压缩”。
我正在尝试解压多个参数包,以便 arr[i][j] = X(i,j)
。但是,我在下面的当前方法中遇到以下错误。是否有使用 C++14/17 实现上述目标的方法?
// Non copyable and default constructable
struct X
{
X(const X&) = delete;
X(int x, int y) : _x(x), _y(y)
{}
int _x;
int _y;
};
X getX(int i, int j)
{
return X(i,j);
}
template <std::size_t ...Xidx, std::size_t ... Yidx>
auto make_2d_array(std::index_sequence<Xidx...>, std::index_sequence<Yidx...>)
{
std::array<std::array<X,sizeof...(Xidx)>, sizeof...(Yidx)> arr = {getX(Xidx, Yidx)...};
return arr;
}
static constexpr std::size_t M = 5;
static constexpr std::size_t N = 6;
int main()
{
std::array<std::array<X,M>, N> arr = make_2d_array(std::make_index_sequence<M>{}, std::make_index_sequence<N>{});
}
错误
<source>:26:87: error: pack expansion contains parameter packs 'Xidx' and 'Yidx' that have different lengths (5 vs. 6)
std::array<std::array<X,sizeof...(Xidx)>, sizeof...(Yidx)> arr = {getX(Xidx, Yidx)...};
~~~~ ~~~~ ^
<source>:35:42: note: in instantiation of function template specialization 'make_2d_array<0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5>' requested here
std::array<std::array<X,M>, N> arr = make_2d_array(std::make_index_sequence<M>{}, std::make_index_sequence<N>{});
^
1 error generated.
Compiler returned: 1
我会这样做
template<std::size_t... XIs, std::size_t... YIs>
std::array<std::array<X, sizeof...(XIs)>, sizeof...(YIs)> make_2d_array(std::index_sequence<XIs...>, std::index_sequence<YIs...>)
{
return {
[](auto YI) -> std::array<X, sizeof...(XIs)> {
return {getX(XIs, YI)...};
}(YIs)...
};
}
是的,有点可怕。原理很简单,我们需要在语法上将 XIs
和 YIs
分开,每个 ...
扩展只解压其中一个,我们需要两个扩展来做“产品”而不是“压缩”。