I have been attempting to implement a compiler generated look-up table containing the values of the sine function. The C++ code looks like this
#include <cstdlib>
#include <cmath>
#include <array>
#include <iostream>
using namespace std;
template<typename T>
constexpr T look_up_table_elem(int i)
{
return {};
}
template<>
constexpr float look_up_table_elem(int i)
{
return sin(static_cast<float>(i)*2*3.14/64);
}
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<float, 65> lookup_table = lookup_table_expand<float, 65>::values;
int main(int argc, char** argv) {
for(const float &item : lookup_table){
std::cout << "Sin: " << item << std::endl;
}
return 0;
}
I have been struggling with the compilation process.
main.cpp: In instantiation of 'struct lookup_table_expand<float, 65>':
main.cpp:49:74: required from here
main.cpp:44:52: error: conversion from 'float' to 'int' in a converted constant expression
44 | : lookup_table_expand<T, L-1, look_up_table_elem<T>(L-1), N...> {};
| ~~~~~~~~~~~~~~~~~~~~~^~~~~
main.cpp:44:52: error: could not convert 'look_up_table_elem<float>((65 - 1))' from 'float' to 'int'
main.cpp:49:76: error: 'values' is not a member of 'lookup_table_expand<float, 65>'
49 | const std::array<float, 65> lookup_table = lookup_table_expand<float, 65>::values;
| ^~~~~~
Can anybody tell me what I am doing wrong?
I do not really understand what you are trying to do here, but the error message indicates that
look_up_table_elem
returns a float and that you are feeding it into anint ...
parameter pack at the following lines:By the way, this is how I would implement a function like this:
Please note that
std::sin
is not a constexpr function (yet?). You would have to write your own compile-time approximation here.And as @HolyBlackCat suggested in a comment below, the following, very simple solution is also possible with modern C++ (>= 17, I think):