使用序列优雅初始化静态(成员)数组

时间:2016-10-08 18:48:28

标签: c++ arrays static initialization c-preprocessor

我想用预定的序列初始化一个静态(可能是常量)数组。 在这种特殊情况下,它将是一个包含数字化正弦波的正弦曲线。

现在,我知道您可以使用以下命令初始化数组:

#define TABLE_SIZE 2000
static float table[TABLE_SIZE] = { 0 , 0.124 , 0.245 , ...  } 

我需要做的就是生成所有正弦值并将其粘贴到内部,但在我看来,这非常难看。

是否有预处理器 指令 lambda 函数或其他内容?

如果不这样,只需要一个计算程序开头计算所有值并将它们分配给静态数组的解决方案?

修改

感谢TemplateRex来自c++11: Create 0 to N constexpr array in c++的回答 ,我有一个有效的解决方案:

#define TABLE_SIZE 2000    
template<class Function, std::size_t... Indices>
    constexpr auto make_array_helper(Function f, std::index_sequence<Indices...>) 
-> std::array<typename std::result_of<Function(std::size_t)>::type, sizeof...(Indices)> 
{
    return {{ f(Indices)... }};
}

template<int N, class Function>
constexpr auto make_array(Function f)
-> std::array<typename std::result_of<Function(std::size_t)>::type, N> 
{
    return make_array_helper(f, std::make_index_sequence<N>{});    
}

constexpr float fun(double x) { return (float)sin(((double)x / (double)TABLE_SIZE) * M_PI * 2.0); }

static constexpr auto sinetable = make_array<TABLE_SIZE>(fun);

不幸的是,我很难将其整合到课堂中。 得到错误:sinetable::make_array is used before its definition,我猜测是因为静态成员是在静态方法之前定义的。或者它可能与constexpr内联有关。

2 个答案:

答案 0 :(得分:1)

您正在寻找的是C ++ 11的constexpr,但您需要递归模板。

c++11: Create 0 to N constexpr array in c++

http://fendrich.se/blog/2012/11/22/compile-time-loops-in-c-plus-plus-11-with-trampolines-and-exponential-recursion/

然而,C ++的标准数学函数是非constexpr所以你无论如何都无法使用它们,所以你可能最好只是在传统的地方初始化它。

答案 1 :(得分:0)

如果你无法通过我不知道的模板技术来实现初始化,这里有另外一种更丑陋的方法:

您只需定义2001宏:

#include <cmath>

#define TABLE_SIZE 2000

#define SINE0 0.0f                          
#define SINE1 SINE0 ,std::sin( 1.0f * M_PI / ( 2 * TABLE_SIZE) )
#define SINE2 SINE1 ,std::sin( 2.0f * M_PI / ( 2 * TABLE_SIZE) )
#define SINE3 SINE2 ,std::sin( 3.0f * M_PI / ( 2 * TABLE_SIZE) )
//...

//...
#define SINE1998 SINE1997 ,std::sin( 1998.0f * M_PI / ( 2 * TABLE_SIZE) )
#define SINE1999 SINE1998 ,std::sin( 1999.0f * M_PI / ( 2 * TABLE_SIZE) )
#define SINE2000 SINE1999 ,std::sin( 2000.0f * M_PI / ( 2 * TABLE_SIZE) )

#define ALL_2001_SINES SINE2000

以这种方式使用它:

#include <iostream>

#include "file_with_macros.hpp" // contains above macros and includes <cmath>

static float const table[TABLE_SIZE+1] = {ALL_2001_SINES}; // + 1 because of inclusion of 
                                                           // both borders 0.0f and M_PI/2

int main()
{
    for(int i=0; i<TABLE_SIZE+1; ++i)
        std::cout << table[i] << ", ";
}

Demo

如果您只需要91个值(每个度数),那么您可以将TABLE_SIZE更改为90,并将宏SINE91移至SINE2000,并定义宏ALL_91_SINESSINE_90