向std::array添加元素

13

由于我无法找到这样的函数(是否不正确?),因此我正在尝试创建一个编译时函数(constexpr函数),该函数接受一个std::array<T,n> arr和一个T t,并返回一个新的std::array<T,n + 1>,其中包含t添加到arr的末尾。我开始尝试以下内容:

template <typename T, int n>
constexpr std::array<T,n+1> append(std::array<T,n> a, T t);

template <typename T>
constexpr std::array<T,1> append(std::array<T,0> a, T t)
{
  return std::array<T,1>{t};
}

template <typename T>
constexpr std::array<T,2> append(std::array<T,1> a, T t)
{
  return std::array<T,2>{a[0], t};
}

我卡住了。我需要一种方法,在初始化列表的前 n 个位置上扩展 a,然后再在末尾添加 t。这可能吗?或者还有其他方法可以做到这一点吗?

2个回答

21
当然,这是可能的:std::index_sequence<I...> 是您的好朋友! 您只需调度到一个函数,该函数接受适当的 std::index_sequence<I...> 作为参数,并使用所有值展开包。例如:
template <typename T, std::size_t N, std::size_t... I>
constexpr std::array<T, N + 1>
append_aux(std::array<T, N> a, T t, std::index_sequence<I...>) {
    return std::array<T, N + 1>{ a[I]..., t };
}
template <typename T, std::size_t N>
constexpr std::array<T, N + 1> append(std::array<T, N> a, T t) {
    return append_aux(a, t, std::make_index_sequence<N>());
}

哇,对我来说纯粹是魔法!C++在最近几年里确实取得了长足的进步。谢谢! - kalj
值得注意的是,对于c++11,有可用的高效实现integer_sequence,例如这个,因为它不幸地不能直接使用。 - W.F.
1
@kalj:实际上,并没有太多的魔法。也许这对我来说很自然,因为我发布了这个答案,导致了相关的提案。;-) - Dietmar Kühl
1
@DietmarKühl,如果这是魔法的话,那么这个答案对我来说就是纯粹的巫术。不过有很多酷炫的东西值得学习! - kalj
注意:需要C++14 -- http://en.cppreference.com/w/cpp/utility/integer_sequence - Brent Bradburn
显示剩余2条评论

1

很容易将Dietmar的答案扩展为一个工具,使您可以constexpr地连接两个数组:

// constexpr util to catenate two array's.
//
// Usage:
//
// constexpr std::array<int, 2> a1 = { 1, 2 };
// constexpr std::array<int, 2> a2 = { 3, 4 };
//
// constexpr auto a3 = catenate_array(a1, a2);

template <typename T, std::size_t N, std::size_t M, std::size_t... I, std::size_t... J>
constexpr std::array<T, N + M>
catenate_array_aux(std::array<T, N> a1, std::array<T, M> a2, std::index_sequence<I...>, std::index_sequence<J...>) {
    return std::array<T, N + M>{ a1[I]..., a2[J]... };
}

template <typename T, std::size_t N, std::size_t M>
constexpr std::array<T, N + M> catenate_array(std::array<T, N> a1, std::array<T, M> a2) {
    return catenate_array_aux(a1, a2, std::make_index_sequence<N>(), std::make_index_sequence<M>());
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接