英文:
Piecewise initialisation of std::array
问题
如何编写一个std::array
连接函数?
template <typename T, std::size_t sza, std::size_t szb>
std::array<T, sza+szb> concat (const std::array<T, sza>& aa,
const std::array<T, szb>& ab)
{
std::array<T, sza+szb> result;
std::copy(std::begin(aa), std::end(aa), std::begin(result));
std::copy(std::begin(ab), std::end(ab), std::begin(result) + sza);
return result;
}
当T
不具备默认构造能力时,这当然是无法工作的。如何修复这个问题?
英文:
How can I write an std::array
concatenation function?
template <typename T, std::size_t sza, std::size_t szb>
std::array<T, sza+szb> concat (const std::array<T, sza>& aa,
const std::array<T, szb>& ab)
{
std::array<T, sza+szb> result;
std::copy(std::begin(aa), std::end(aa), std::begin(result));
std::copy(std::begin(ab), std::end(ab), std::begin(result) + sza);
return result;
}
This of course doesn't work when T
is not default-constructible. How can this be fixed?
答案1
得分: 13
C++20 引入了像n. m.的答案中展示的显式lambda模板参数列表。
C++14 的解决方案需要一个辅助函数:
template <typename T, std::size_t... ai, std::size_t... bi>
std::array<T, sizeof...(ai) + sizeof...(bi)>
concat_impl(std::array<T, sizeof...(ai)> const& aa,
std::array<T, sizeof...(bi)> const& ab,
std::index_sequence<ai...>, std::index_sequence<bi...>)
{
return std::array<T, sizeof...(ai) + sizeof...(bi)>{
aa[ai]..., ab[bi]...
};
};
template <typename T, std::size_t sza, std::size_t szb>
std::array<T, sza + szb> concat (std::array<T, sza> const& aa,
std::array<T, szb> const& ab)
{
return concat_impl(aa, ab,
std::make_index_sequence<sza>{},
std::make_index_sequence<szb>{});
}
英文:
Explicit template parameter list for lambdas, as shown in n. m.'s answer, were introduced in C++20.
A C++14 solution needs an helper function:
template <typename T, std::size_t... ai, std::size_t... bi>
std::array<T, sizeof...(ai) + sizeof...(bi)>
concat_impl(std::array<T, sizeof...(ai)> const& aa,
std::array<T, sizeof...(bi)> const& ab,
std::index_sequence<ai...>, std::index_sequence<bi...>)
{
return std::array<T, sizeof...(ai) + sizeof...(bi)>{
aa[ai]..., ab[bi]...
};
};
template <typename T, std::size_t sza, std::size_t szb>
std::array<T, sza + szb> concat (std::array<T, sza> const& aa,
std::array<T, szb> const& ab)
{
return concat_impl(aa, ab,
std::make_index_sequence<sza>{},
std::make_index_sequence<szb>{});
}
答案2
得分: 12
将参数转换为使用 std::index_sequence
和一个辅助 lambda 函数的参数包展开。
template <typename T, std::size_t sza, std::size_t szb>
std::array<T, sza+szb> concat (const std::array<T, sza>& aa,
const std::array<T, szb>& ab)
{
auto doit = [&](std::index_sequence<ai...>, std::index_sequence<bi...>)
{
return std::array<T, sza+szb>{aa[ai]..., ab[bi]...};
};
return doit(std::make_index_sequence<sza>{}, std::make_index_sequence<szb>{});
}
英文:
Convert the parameters to parameter-pack expansions with std::index_sequence
and a helper lambda.
template <typename T, std::size_t sza, std::size_t szb>
std::array<T, sza+szb> concat (const std::array<T, sza>& aa,
const std::array<T, szb>& ab)
{
auto doit = [&]<std::size_t... ai, std::size_t... bi>
(std::index_sequence<ai...>, std::index_sequence<bi...>)
{
return std::array<T, sza+szb>{aa[ai]..., ab[bi]...};
};
return doit(std::make_index_sequence<sza>{}, std::make_index_sequence<szb>{});
}
答案3
得分: 6
使用std::tuple_cat
和std::apply
的帮助,您可以
template <typename T, std::size_t sza, std::size_t szb>
std::array<T, sza+szb> concat(const std::array<T, sza>& aa,
const std::array<T, szb>& ab)
{
return std::apply([](auto... elems) { return std::array{elems...}; },
std::tuple_cat(aa, ab));
}
英文:
With the help of std::tuple_cat
and std::apply
, you can
template <typename T, std::size_t sza, std::size_t szb>
std::array<T, sza+szb> concat(const std::array<T, sza>& aa,
const std::array<T, szb>& ab)
{
return std::apply([](auto... elems) { return std::array{elems...}; },
std::tuple_cat(aa, ab));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论