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