RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1407454
Accepted
Denver Toha
Denver Toha
Asked:2022-07-07 19:15:15 +0000 UTC2022-07-07 19:15:15 +0000 UTC 2022-07-07 19:15:15 +0000 UTC

如何编写compile_time排序?

  • 772

最近我需要编写一个编译时排序。由于我们项目使用c++17,std::sort不是constexpr,20标准还没有完全支持。

我决定分享我的算法,如果他们改进它或告诉我错误,我会很高兴

c++ шаблоны-с++
  • 2 2 个回答
  • 52 Views

2 个回答

  • Voted
  1. Best Answer
    HolyBlackCat
    2022-07-08T19:08:57Z2022-07-08T19:08:57Z

    只需像往常一样编写排序,并将其附加到constexpr.

    #include <array>
    #include <iostream>
    #include <utility>
    
    template <typename T>
    constexpr void sort(T *begin, T *end)
    {
        for (T *mid = end; mid > begin;)
        {
            mid--;
            for (T *cur = begin; cur < mid; cur++)
            {
                if (cur[0] > cur[1])
                {
                    T tmp(std::move(cur[0]));
                    cur[0] = std::move(cur[1]);
                    cur[1] = std::move(tmp);
                }
            }
        }
    }
    
    constexpr std::array<int, 4> foo()
    {
        std::array<int, 4> ret = {2,4,3,1};
        sort(ret.data(), ret.data() + ret.size());
        return ret;
    }
    
    int main()
    {
        constexpr auto arr = foo();
        for (int x : arr)
            std::cout << x << '\n';
    }
    
    • 1
  2. Denver Toha
    2022-07-07T19:15:15Z2022-07-07T19:15:15Z

    由于没有必要在编译时对大数组进行排序(也没有必要),所以我实现了最简单的插入排序。

    // енум нужен для примера, так как для моей задачи необходимо сортировать пары enum - строка
    enum class MinLimValue : uint16_t
    {
        NONE                 = 0,  // значение не задано
        // 0 - 3 бит - PPE
        MIN_BANNER_PPE       = 1 << 0,
        // 4 - 7 бит - cpm
        REQUEST_MIN_CPM      = 1 << 4,
        PAD_MIN_CPM          = 1 << 5,
        MIN_CPM_BY_ALIVE_CPM = 1 << 6,
    };
    
    namespace compile_time {
    
        // swapt для простых объектов и объектов с constexpr оператором присваивания
        template<typename T>
        constexpr void swap(T & aLeft, T & aRight) {
              T sTmp = aLeft;
              aLeft = aRight;
              aRight = sTmp;
        }
       
        // следующие 3 перегрузки нужны для свапа картежей
        template<size_t I, typename... T>
        constexpr void swap(std::tuple<T...> & aLeft, std::tuple<T...>& aRight)
        {
            auto& sLeft = std::get<I>(aLeft);
            auto& sRight = std::get<I>(aRight);
            auto sTmp = sLeft;
            sLeft = sRight;
            sRight = sTmp;
        }
    
        template<size_t... I, typename... T>
        constexpr void swap(std::tuple<T...> & aLeft, std::tuple<T...>& aRight,  std::index_sequence<I...>)
        {
            ([&]{ swap<I>(aLeft, aRight);}(), ...);
        }
    
        template<typename... T>
        constexpr void swap(std::tuple<T...> & aLeft, std::tuple<T...>& aRight)
        {
            constexpr auto sSize = std::tuple_size<std::tuple<T...>>{};
            swap(aLeft, aRight, std::make_index_sequence<sSize>{});
        }
    
        template<size_t I, typename T>
        constexpr void innerLoop(T& arr) {
            if constexpr(I == 0) {
                return;
            }
            for (size_t i = I; i > 0 && arr[i - 1] > arr[i]; i--) {
                compile_time::swap(arr[i - 1], arr[i]);
            }
        }
    
        template<typename T, std::size_t ...I>
        constexpr void outerLoop(T & arr, std::index_sequence<I...>)
        {
            ([&] {
                innerLoop<I>(arr);
            }(), ...);
        }
    
        template<size_t Size, typename T>
        constexpr void sort(T& arr)
        {
            outerLoop(arr, std::make_index_sequence<Size>());
        }
    
    
        // для примера, чтоб проверить работает ли наша сортировка в comp
        constexpr auto makeArr()
        {
            std::array<std::tuple<MinLimValue, int>, 5> sTest{std::make_tuple(MinLimValue::NONE, 5),
                                                                     std::make_tuple(MinLimValue::PAD_MIN_CPM,3),
                                                                     std::make_tuple(MinLimValue::MIN_CPM_BY_ALIVE_CPM,5),
                                                                     std::make_tuple(MinLimValue::MIN_BANNER_PPE,10),
                                                                     std::make_tuple(MinLimValue::REQUEST_MIN_CPM,89)};
            sort<5>(sTest);
            return sTest;
        }
    }
    
    int main() {
    
        constexpr auto sArr = compile_time::makeArr();
    
        return 0;
    }
    

    不幸的是,我无法创建一个嵌套循环,以便嵌套计数器使用 compile_time 获取一个变量值,编译器被诅咒了,所以在排序的 2 个循环中,我实现了函数。

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5