程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了如何在 C++ 编译时生成查找表?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决如何在 C++ 编译时生成查找表??

开发过程中遇到如何在 C++ 编译时生成查找表?的问题如何解决?下面主要结合日常开发的经验,给出你关于如何在 C++ 编译时生成查找表?的解决方法建议,希望对你解决如何在 C++ 编译时生成查找表?有所启发或帮助;

我一直在尝试实现一个编译器生成的查找表 包含正弦函数的值。 C++ 代码看起来像这样

#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,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;
}

我一直在为编译过程苦苦挣扎。

@H_429_5@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,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>::values;
      |                                                                            ^~~~~~

谁能告诉我我做错了什么?

解决方法

我不太明白您在此处尝试做什么,但错误消息表明 look_up_table_elem 返回一个浮点数,并且您在以下几行将其输入到 int ... 参数包中:

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...> {};

便说一句,这就是我将如何实现这样的功能:

constexpr float lookup_table_elem(std::size_t i,std::size_t n)
{
    return static_cast<float>(i) / static_cast<float>(n); // Have a constexpr sin function here!
}

template <class T>
struct lookup_table_impl;

template <std::size_t... I>
struct lookup_table_impl<std::index_sequence<I...>>
{
    static constexpr std::size_t N = sizeof...(I);
    static constexpr std::array<float,N> values{ lookup_table_elem(I,N) ... };
};

template <std::size_t N>
using lookup_table = lookup_table_impl<std::make_index_sequence<N>>;

template <std::size_t N>
constexpr auto lookup_table_values = lookup_table<N>::values;

请注意,std::sin 不是 constexpr 函数(还有吗?)。您必须在此处编写自己的编译时近似值。

正如@HolyBlackCat 在下面的评论中所建议的那样,现代 C++ 也可以使用以下非常简单的解决方案(我认为 >= 17):

template <std::size_t N>
constexpr std::array<float,N> make_lookup_table()
{
    std::array<float,N> v;
    for (std::size_t i = 0u; i < N; ++i)
    {
        v[i] = static_cast<float>(i); // Insert constexpr sin function here!
    }
    return v;
}

template <std::size_t N>
constexpr auto lookup_table_values = make_lookup_table<N>();
,

生成LUT的代码可能会大大简化:

template <std::size_t N,typename F = std::identity>
constexpr auto gen_float_array(const F& f = F{}) 
{
   std::array<float,N> arr;
   for (std::size_t i = 0; i < N; ++i)
      arr[i] = f(static_cast<float>(i));

   return arr;
}

可以如下使用:

constexpr auto lookup_map =
      gen_float_array<32>([](auto f) { 
        return f * 3.14f; // here could a call be placed to a constexpr sin function
      });

例:https://godbolt.org/z/ssEhK6bd7

正如 Markus Mayr 所指出的,您仍然需要一个 constexpr sin 函数来为您的用例获得所需的结果。

大佬总结

以上是大佬教程为你收集整理的如何在 C++ 编译时生成查找表?全部内容,希望文章能够帮你解决如何在 C++ 编译时生成查找表?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。