C++ 我如何适应旧的C风格#使用现代C#x2B定义映射#+;?

C++ 我如何适应旧的C风格#使用现代C#x2B定义映射#+;?,c++,C++,在旧的C头文件中,我有以下映射(32行长): 在C++中,我可以有一个函数,它接受索引并返回int。这样,我只在一行中初始化一个数组,但是它不会很容易读取。 我想用现代风格来用C++取代它。 我曾想过使用lambdas这样的东西: #include <array> class test { int icon_index(int pio_index) { const std::array<int, 32> iocon_index = [](

在旧的C头文件中,我有以下映射(32行长):

在C++中,我可以有一个函数,它接受索引并返回int。这样,我只在一行中初始化一个数组,但是它不会很容易读取。 我想用现代风格来用C++取代它。 我曾想过使用lambdas这样的东西:

#include <array>
class test 
{
    int icon_index(int pio_index)
    {
        const std::array<int, 32> iocon_index = [](){
            std::array<int, 32> buf;
            buf[17] = 0;
            buf[13] = 1;
            buf[12] = 2;
            //...
            return buf;
        }();
        return iocon_index[pio_index];
    }
};
#包括在内,它似乎是巨大的。我还想知道它将使用什么RAM

我必须使用兼容C++14的编译器,因此:

  • 用C++14替换这个遗留C代码的最佳方式是什么
  • 用C++17替换这个遗留C代码的最佳方式是什么
  • constexpr
    可能是答案的一部分

    [编辑]我不想替换C代码,但要使其具有一个函数,该函数接受一个int作为参数并返回另一个int。它在一个小型嵌入式系统上运行,因此我希望它尽可能紧凑(在闪存和RAM方面)。

    使用C++17

    const std::array<int, 32> iocon_index = [](){
        std::array<int, 32> buf;
    
    编辑2:
    为了使它更具可读性,我们可以这样做

    struct array_assign
    {
        constexpr
        array_assign(std::array<int, 32>& arr) :
            arr(arr)
        { }
    
        constexpr int& operator[](std::size_t idx)
        {
            return const_cast<int&>(this->arr[idx]);
        }
    
        const std::array<int, 32>& arr;
    };
    
    struct数组\u赋值
    {
    常量表达式
    数组分配(std::数组和arr):
    arr(arr)
    { }
    constexpr int&运算符[](std::size\u t idx)
    {
    返回const_cast(this->arr[idx]);
    }
    常数std::数组和arr;
    };
    
    然后

    std::array<int, 32> buf2 { };
    array_assign buf(buf2);
    
    buf[17] = 0;
    buf[13] = 1;
    buf[12] = 2;
    ...
    return buf2;
    
    std::数组buf2{};
    数组分配buf(buf2);
    buf[17]=0;
    buf[13]=1;
    buf[12]=2;
    ...
    返回buf2;
    
    您可以创建一个constexpr,而不是lambda:

    #include <utility>
    int icon_index(int pio_index)
    {
    
        constexpr std::pair<int, int> map_items[] = {
            {10, 1},
            {11, 15},
            {12, 3},
            {13, 32},
            {14, 9},
            {15, 8},
            {16, 9},
            {17, 7},
            {18, 6},
            {19, 5},
            {45, 4}
        };
    
        for (auto item : map_items)
        {
            if (pio_index == item.first)
            {
                return item.second;
            }
        }
    
        return 0; /// not found
    }
    
    #包括
    int图标索引(int pio索引)
    {
    constexpr std::对映射_项[]={
    {10, 1},
    {11, 15},
    {12, 3},
    {13, 32},
    {14, 9},
    {15, 8},
    {16, 9},
    {17, 7},
    {18, 6},
    {19, 5},
    {45, 4}
    };
    用于(自动项目:映射项目)
    {
    if(pio_索引==项目优先)
    {
    返回项。秒;
    }
    }
    返回0;///未找到
    }
    
    我想您也可以使用std::array,但这是一个可以使用任何类型对的映射。使用constexpr意味着它是在编译时生成的

    更新:
    #包括
    constexpr int find_项(int idx)
    {
    std::配对映射_项[]={
    {10, 1},
    {11, 15},
    {12, 3},
    {13, 32},
    {14, 9},
    {15, 8},
    {16, 9},
    {17, 7},
    {18, 6},
    {19, 5},
    {45, 4}
    };
    用于(自动项目:映射项目)
    {
    if(idx==项。第一个)
    返回项。秒;
    }
    返回0;
    }
    int main()
    {
    constexpr int i=查找项目(12);
    返回i;//返回3
    }
    
    不太清楚你的第二个是如何取代第一个的。第一个仅定义了一些预处理器符号,但没有索引(仅在名称中),谢谢!对于那些想看到C++17版本的人:但是我不能让它与C++14一起工作,因为std::array的[]运算符:。你知道为什么吗?编辑这篇文章是为了反映
    std::array::operator[](…)
    在c++14中不是
    constexpr
    ,谢谢你的更新。如果我们平衡代码可读性和程序集输出,那么我认为最好为C++14使用@code_fodder解决方案,最好为C++17使用您的解决方案。这是一个很好的解决方案,但输出的程序集代码似乎更大@维克多啊,大部分都是for循环我想你们的主要问题是地图的存储。你可以把find循环变成一个const expr,这样就减少了汇编代码的行数,见updated…上面的代码编译成大约11行汇编代码,并返回3:为什么你要把每个
    的好看的
    改成丑陋的
    ,而
    ?@Mestkon我认为你不能在constexpr中处理循环。。。至少我认为你可以——我记得不久前读到过关于这方面的文章,但老实说,我没有尝试。。。我会马上试试。。。
    struct array_assign
    {
        constexpr
        array_assign(std::array<int, 32>& arr) :
            arr(arr)
        { }
    
        constexpr int& operator[](std::size_t idx)
        {
            return const_cast<int&>(this->arr[idx]);
        }
    
        const std::array<int, 32>& arr;
    };
    
    std::array<int, 32> buf2 { };
    array_assign buf(buf2);
    
    buf[17] = 0;
    buf[13] = 1;
    buf[12] = 2;
    ...
    return buf2;
    
    #include <utility>
    int icon_index(int pio_index)
    {
    
        constexpr std::pair<int, int> map_items[] = {
            {10, 1},
            {11, 15},
            {12, 3},
            {13, 32},
            {14, 9},
            {15, 8},
            {16, 9},
            {17, 7},
            {18, 6},
            {19, 5},
            {45, 4}
        };
    
        for (auto item : map_items)
        {
            if (pio_index == item.first)
            {
                return item.second;
            }
        }
    
        return 0; /// not found
    }
    
    #include <utility>
    
    constexpr int find_item(int idx)
    {
        std::pair<int, int> map_items[] = {
            {10, 1},
            {11, 15},
            {12, 3},
            {13, 32},
            {14, 9},
            {15, 8},
            {16, 9},
            {17, 7},
            {18, 6},
            {19, 5},
            {45, 4}
        };
    
        for (auto item : map_items)
        {
            if (idx == item.first)
            return item.second;
        }
    
        return 0;
    }
    
    int main()
    {
        constexpr int i = find_item(12);
        return i; // returns 3
    }