初始化 C++11 数组的最佳方法,主要是标识映射
Best way to initialize a C++11 array that's mostly the identity mapping
我现在有一些代码看起来像这样:
#define ______ 0x0000
static const uint16_t plane0[256] = {
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005A, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, 0x039C, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
...
};
#undef ______
uint16_t caseup(uint16_t wc)
{
return (plane0[wc] == 0x0000) ? wc : plane0[wc];
}
我真的很想用一个简单的return plane0[wc]
替换该caseup
函数。从大局来看,额外的比较和分支可能不是很昂贵,但如果我们摆脱它,代码肯定会更有效率。
但我不想重写表格。甚至没有使用工具来重写它——我不希望我们的案例映射表被大量垃圾十六进制值弄乱。我希望表格大部分保持原始的宏观化,十六进制值仅在实际需要非标识大小写映射的地方。
在 C++11 中执行此操作的最干净方法是什么?
我想到了这个:
template<int N>
struct PlaneMapping {
uint16_t i;
uint16_t data[N];
template<typename... Args>
constexpr PlaneMapping(Args... a) : i(0), data { uint16_t(a ? (i++,a) : i++)... }
{}
};
static const PlaneMapping<256> plane0(
______, ______, ______, ______, ______, ______, ______, ______,
______, ______, ______, ______, ______, ______, ______, ______,
...
);
uint16_t caseup(uint16_t wc)
{
return plane0.data[wc];
}
我猜这相当干净,但所有这些i++
都是丑陋的,你必须传递-O1
或更好的,然后它才能一直编译为静态数据,而不是从_main
运行大量代码。有没有更清洁的解决方案?
在这种情况下,我建议不要执行此类优化,除非分析显示这是一个瓶颈。就像你说的,你喜欢表的清洁度(更易于阅读/维护),如果性能在这里不是关键,你想保留这些属性。
另一方面,有一种方法可以交换空间和时间:制作数组的另一个副本,并翻译值;你只需要执行一次复制/翻译,在caseup()中,这个新数组被查找而不分支。原始数组没有更改,并且仍然干净且易于更改。
static const uint16_t plane0lookup[256];
for(uint16_t i = 0; i<256; ++i)
{
plane0lookup[i] = (plane0[wc] == 0x0000) ? i : plane0[wc];
}
uint16_t caseup(uint16_t wc)
{
return plane0lookup[wc];
}
uint16_t caseup(uint16_t wc)
{
static const std::array<uint16_t, 256> plane0Map = [&]
{
std::array<uint16_t, 256> mapping;
for(size_t i = 0; i < 256; ++i)
mapping[i] = plane0[i] == 0 ? i : plane0[i];
return mapping;
}();
return plane0Map[wc];
}
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 将函数类成员映射到类本身内部
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 使用std::函数映射对象方法
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++映射分割错误(核心转储)
- 内联映射初始化的动态atexit析构函数崩溃
- 使用"std::unordereded_map"映射到"std::list"对象
- 如何从多映射中删除特定的重复项
- 在未初始化映射的情况下,将值插入到映射的映射中
- QT通过C++添加映射QML项目
- 在c++中访问int到类对象的映射时出错
- 在C++中搜索嵌套多映射值
- 错误处理.将系统错误代码映射到泛型
- C++匿名结构作为std::映射值
- 如何从存储在std::映射中的std::集中删除元素
- 递归无序映射
- 初始化 C++11 数组的最佳方法,主要是标识映射