通用Constexpr查找表
Generic Constexpr Lookup Table C++11
我试图构建一个通用的查找表,它需要一个生成器函数并在编译时创建表。下面是表和生成的代码:
#ifndef CONSTEXPR_LOOKUPTABLE_H
#define CONSTEXPR_LOOKUPTABLE_H
#include <cstddef>
/* Generate a range */
template <std::size_t... Is>
struct seq{};
template <std::size_t N, std::size_t... Is>
struct gen_seq : gen_seq<N - 1, N - 1, Is...>{};
template <std::size_t... Is>
struct gen_seq<0, Is...> : seq<Is...>{};
/*
The lookup table consisting of values to be
computed at compile-time
*/
template<std::size_t N, class T>
struct LookUpTable{
std::size_t indexes[N];
T values[N];
static constexpr std::size_t length = N;
};
/*
Generate the table from a generator function
*/
template <class Lambda, std::size_t... Is>
constexpr auto LookUpTableGenerator(seq<Is...>, Lambda f) ->
LookUpTable<sizeof...(Is), decltype(f(Is)...)>
{
return {{ Is... }, { f(Is)... }};
}
template <std::size_t N, class Lambda>
constexpr auto LookUpTableGenerator(Lambda f) ->
decltype(LookUpTableGenerator(gen_seq<N>{}, f))
{
return LookUpTableGenerator(gen_seq<N>{}, f);
}
#endif
下面是主要函数:
#include <iostream>
#include <memory>
#include <vector>
#include <string>
#include "ConstExprLookupTable.h"
typedef unsigned short ushort;
typedef unsigned char byte;
/*
There are only 10 digits (0 - 9)
*/
static constexpr ushort DIGITS = 10;
/*
A table to prevent repeated division calculation:
table[i][j] = (i + j) / 10;
*/
static constexpr ushort carry_table[DIGITS][DIGITS] =
{
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
{0, 0, 0, 0, 0, 0, 1, 1, 1, 1},
{0, 0, 0, 0, 0, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 1, 1, 1, 1, 1, 1},
{0, 0, 0, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
static constexpr double myFunc(double x)
{
return x / DIGITS;
}
int main()
{
constexpr std::size_t length = 100;
auto table = LookUpTableGenerator<length>(myFunc);
for (auto v : table.values){
std::cout << v << " ";
}
std::cout << "n";
}
但是,这会产生以下编译时错误:
ConstExprLookupTable.h:33:46: error: template argument 2 is invalid
LookUpTable<sizeof...(Is), decltype(f(Is)...)>
^
ConstExprLookupTable.h:33:46: error: template argument 2 is invalid
ConstExprLookupTable.h:33:46: error: template argument 2 is invalid
ConstExprLookupTable.h:33:46: error: template argument 2 is invalid
ConstExprLookupTable.h:33:46: error: template argument 2 is invalid
ConstExprLookupTable.h:33:46: error: template argument 2 is invalid
ConstExprLookupTable.h:33:46: error: template argument 2 is invalid
ConstExprLookupTable.h:33:46: error: template argument 2 is invalid
ConstExprLookupTable.h:33:46: error: template argument 2 is invalid
ConstExprLookupTable.h:33:1: error: invalid use of template-name ‘LookUpTable’ without an argument list
LookUpTable<sizeof...(Is), decltype(f(Is)...)>
^
ConstExprLookupTable.h:33:12: error: expected initializer before ‘<’ token
LookUpTable<sizeof...(Is), decltype(f(Is)...)>
^
virt.cpp: In function ‘int main()’:
virt.cpp:88:53: error: no matching function for call to ‘LookUpTableGenerator(double (&)(double))’
auto table = LookUpTableGenerator<length>(myFunc);
我的问题是(最后!)这可能吗?当我用一个具体类型(比如double
)替换查找表的class T
参数时,代码可以很好地编译。2)我认为错误在这里:
template <class Lambda, std::size_t... Is>
constexpr auto LookUpTableGenerator(seq<Is...>, Lambda f) ->
LookUpTable<sizeof...(Is), decltype(f(Is)...)>
{
return {{ Is... }, { f(Is)... }};
}
它似乎不像decltype
。在这种情况下,decltype
应该是什么?
可以在很多情况下扩展包,但decltype
不是其中之一。您必须将包包装在某个提取类型的元函数中。就像:
template <typename T, typename... >
using first = T;
然后使用它:
template <class Lambda, std::size_t... Is>
constexpr auto LookUpTableGenerator(seq<Is...>, Lambda f) ->
LookUpTable<sizeof...(Is), first<decltype(f(Is))...>>
虽然因为所有的Is
都是相同的类型(size_t
),你可以直接使用:
template <class Lambda, std::size_t... Is>
constexpr auto LookUpTableGenerator(seq<Is...>, Lambda f) ->
LookUpTable<sizeof...(Is), decltype(f(std::declval<size_t>()))>
相关文章:
- 正在查找文档以获得PS4平台的C++中的设备信息
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 在C++中查找文件
- 多成员Constexpr结构初始化
- 模板元程序查找相似的连续类型名称
- 在UNIX系统中使用DIR查找文件的字节大小
- 条件constexpr函数
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- 查找最接近的大于当前数字的数字的索引
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 查找后更改类变量
- Visual C++ constexpr Hints
- 使用正则表达式regex_search在字符串中查找字符串
- 如何确认我的constexpr表达式实际上已经在编译时执行
- C++constexpr数组查找:内存开销?其他问题
- 带有 constexpr 的查找表
- Constexpr查找表与VS2015
- Constexpr查找实现
- 通用Constexpr查找表
- 在模板类的constexpr函数中查找正确的宏常量