2016-10-08 26 views
0

我想用一個預先確定的序列初始化一個大的靜態(可能是常量)數組。 在這種特殊情況下,它將成爲一個可調節的,包含數字化的正弦波。帶序列的靜態(成員)數組的優雅初始化

現在,我知道你可以初始化數組:

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

和所有我需要做的是生成所有的正弦值,並將其粘貼裏面,但在我看來這是非常醜陋。

是否有預處理指令拉姆達功能或東西嗎?

失敗了,只是一個解決方案來計算程序開始時的所有值,並將它們分配給靜態數組?

編輯:

由於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有關。

+4

你可以使用C++ 11中的'constexpr'嗎? – Rakete1111

+0

看看我很老的答案:) http://stackoverflow.com/questions/35389493/is-it-possible-to-evaluate-array-on-compilation-time/35390025#35390025。純粹的醜陋!只需定義2000個宏,你就很好。 – xinaiz

+0

你在'fun'中有2個'return' :)我仍然認爲這是一個黑客,'float [N]'與'std :: array不一樣'':( – xinaiz

回答

0

你在找什麼是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

你知道浮動點數不能是模板'非類型'參數吧? – xinaiz

+0

嗯?你是什麼意思? 我認爲這裏比較大的問題是沒有一個std :: math是非constexpr –

+0

第一個鏈接的第二個答案是複製粘貼提供了工作結果,但是我將不得不研究這個難以理解的模板嚮導幾天。謝謝! –

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_SINES定義爲SINE_90