You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++14中如何反转任意std::integer_sequence的整数顺序

问题描述

我有时需要反转index_sequence中的值,再使用反转后的结果反转类元组(tuple-like)对象内的元素,例如下方示例就实现了编译期反转constexpr修饰的std::array:

#include <array>
#include <cstdint>
#include <utility>

namespace detail {
template <class T, std::size_t N, std::size_t... I>
    constexpr std::array<T, N> rev_arr_helper(const std::array<T, N>& arr,
                                              std::index_sequence<I...>) {
        return {arr[sizeof...(I) - I - 1]...};

        //     {arr[4-0-1], arr[4-1-1], arr[4-2-1], arr[4-3-1]}
        //     =>
        //     {arr[3], arr[2], arr[1], arr[0]}
    }
}  // namespace detail

template <class T, std::size_t N>
constexpr std::array<T, N> rev_arr(const std::array<T, N>& arr) {
    return detail::rev_arr_helper(arr, std::make_index_sequence<N>{});
}

int main() {
    constexpr std::array<int, 4> arr{11, 22, 33, 44};
    constexpr auto rev = rev_arr(arr);    
    static_assert(rev[0] == 44 && rev[1] == 33 && rev[2] == 22 && rev[3] == 11, "");
}

但上述方案仅支持元素按0, 1, 2, ..., N-1顺序排列的索引序列,无法适配任意integer_sequence(例如std::integer_sequence<int, 4, -5, 7, -3>)。需要在C++14标准下让如下代码可正常编译:

#include <type_traits>
#include <utility>

int main() {
    std::integer_sequence<int, 4, -5, 7, -3> iseq;
    std::integer_sequence<int, -3, 7, -5, 4> itarget;

    auto irev = reverse_sequence(iseq);

    static_assert(std::is_same<decltype(irev), decltype(itarget)>::value, "");
}

需要实现通用的reverse_sequence功能达成上述需求。


实现方案

原有反转array的方案本质是直接计算反转后的索引值,仅适配连续0起始的索引序列,通用实现通过存储原序列所有值、按位置反向取值的逻辑,即可支持任意值的整数序列反转,完全符合C++14标准要求。

完整实现代码如下:

#include <type_traits>
#include <utility>

namespace detail {
template <class T, T... Vals, std::size_t... Idx>
constexpr auto reverse_sequence_helper(std::integer_sequence<T, Vals...>,
                                       std::index_sequence<Idx...>) {
    constexpr T val_arr[] = {Vals...};
    return std::integer_sequence<T, val_arr[sizeof...(Idx) - 1 - Idx]...>{};
}
}  // namespace detail

template <class T, T... Vals>
constexpr auto reverse_sequence(std::integer_sequence<T, Vals...> seq) {
    return detail::reverse_sequence_helper(
        seq,
        std::make_index_sequence<sizeof...(Vals)>{}
    );
}

实现逻辑

  • 对外接口接收任意std::integer_sequence实例,自动推导序列元素类型和所有元素值
  • 调用辅助函数时,通过std::make_index_sequence生成和原序列长度一致、从0起始的连续索引序列
  • 辅助函数中将原序列的所有元素存入constexpr数组,包展开时按「序列长度-1-当前索引」的规则从数组中取对应位置的值,构造出反转后的新std::integer_sequence返回

注:该实现同时兼容std::index_sequence(其本身是std::integer_sequence<std::size_t, ...>的类型别名),可直接复用在类元组元素反转、编译期序列变换等场景中。

将上述实现和测试代码联合编译,可正常通过static_assert类型校验,返回结果和预期的反转后序列完全一致。


内容的提问来源于stack exchange,提问作者Ted Lyngmo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 18:16:01