std::array 的分段初始化

n. *_* m. 15 c++ stdarray c++20

如何编写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;
}
Run Code Online (Sandbox Code Playgroud)

T当不可默认构造时,这当然不起作用。如何解决这个问题?

Bob*_*b__ 13

C++20 中引入了lambda 的显式模板参数列表,如nm答案所示。

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>{});
}
Run Code Online (Sandbox Code Playgroud)


n. *_* m. 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::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>{});
}
Run Code Online (Sandbox Code Playgroud)

  • 这不是 c++14 (2认同)

康桓瑋*_*康桓瑋 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));
}
Run Code Online (Sandbox Code Playgroud)