使用 c++ 的余弦查找表
Cosine lookup table with c++
这是一个片段,应该生成一个包含 2048 个元素的余弦查找表,取自顾昌义的《构建嵌入式系统》一书:
#include <cmath>
#include <array>
template<typename T>
constexpr T look_up_table_elem (int i) {
return {};
}
template<>
constexpr uint16_t look_up_table_elem (int i) {
return round (cos (static_cast <long double>(i) / 2048 * 3.14159 / 4) * 32767);
}
template<typename T, int... N>
struct lookup_table_expand{};
template<typename T, int... N>
struct lookup_table_expand<T, 1, N...> {
static constexpr std::array<T, sizeof...(N) + 1> values = {{ look_up_table_elem<T>(0), N... }};
};
template<typename T, int L, int... N>
struct lookup_table_expand<T, L, N...>: lookup_table_expand<T, L-1, look_up_table_elem<T>(L-1), N...> {};
template<typename T, int... N>
constexpr std::array<T, sizeof...(N) + 1> lookup_table_expand<T, 1, N...>::values;
const std::array<uint16_t, 2048> lookup_table = lookup_table_expand<uint16_t, 2048>::values;
注:写于C++11。
我主要来自一个Java世界,我对C++的基础知识有很好的掌握。由于书中从未真正解释过,我真的很困惑这个片段是如何完成任务的,以及它是如何实现以下目标的(也摘自书(:
模板专用化和类继承将帮助我们摆脱 constexpr 函数只能将返回状态作为其函数体的限制,这就是为什么在表大小增加时必须手动填充查找表的原因。
任何帮助将不胜感激。我理解带有 constexpr 模板的部分,它会生成实际值,但我真的不确定结构在做什么以及如何构建最终数组。
首先,让我们看一下以下行:
const std::array<uint16_t, 2048> lookup_table =
lookup_table_expand<uint16_t, 2048>::values;
在那里,lookup_table
将从lookup_table_expand<uint16_t, 2048>
结构内部保存values
数组复制构建。这很简单,现在让我们看看完成模板实例化时会发生什么。
我们有一个正文为空的主模板(前向声明就足够了,我们不会以这种形式使用它(:
template<typename T, int... N>
struct lookup_table_expand {
};
lookup_table_expand<uint16_t, 2048>
将匹配主模板的以下部分专用化:
template<typename T, int L, int... N>
struct lookup_table_expand<T, L, N...> :
lookup_table_expand<T, L - 1, look_up_table_elem<T>(L - 1), N...> {
};
因为上面的模板的继承将使用不断增长的模板参数列表递归实例化,直到当前模板与主模板的以下部分专用化不匹配:
template<typename T, int... N>
struct lookup_table_expand<T, 1, N...> {
static constexpr std::array<T, sizeof...(N) + 1> values = {{
look_up_table_elem<T>(0), N...
}};
};
当L
在递归中变得1
时,将发生与上述模板的匹配。此时模板参数列表 (N...
( 将包含以下函数的调用结果,其值从 1 到 2047:
constexpr uint16_t look_up_table_elem(int i) {
return round(cos(static_cast<long double>(i) / 2048 * 3.14159 / 4) * 32767);
}
这是模板的唯一成员(values
(lookup_table_expand
将使用模板参数列表的值进行初始化的地方。
请注意,values
是一个static constexpr
数据成员,可以在class
/struct
声明中初始化,因此甚至不需要以下行:
template<typename T, int... N>
constexpr std::array<T, sizeof...(N) + 1> lookup_table_expand<T, 1, N...>::values;
values
数组将由lookup_table_expand<uint16_t, 2048>
继承,因此最终您可以从该结构访问它。
- 正在查找文档以获得PS4平台的C++中的设备信息
- 在C++中查找文件
- 模板元程序查找相似的连续类型名称
- 在UNIX系统中使用DIR查找文件的字节大小
- 查找最接近的大于当前数字的数字的索引
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 查找后更改类变量
- 使用正则表达式regex_search在字符串中查找字符串
- 使用gcc从静态链接的文件中查找可选符号
- 在C++中查找范围的长度
- 算法问题:查找从堆栈中弹出的所有序列
- 在Windows中查找扬声器输出的当前音量级别
- 如何在C++中使用X509证书模在令牌中查找私钥
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 在 for 循环中查找问题时遇到困难
- 如何在文件中查找字节序列
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 使用堆查找第K个最大元素的时间复杂性
- 使用 c++ 的余弦查找表