2012-08-27 66 views
4

我試圖通過在編譯時計算數字序列並將它們存儲爲靜態向量來節省計算時間(但我可能會在運行時的開始處爲計算解決一次現在)。什麼我試圖做一個簡單的(未編譯)的例子是:使用函數調用初始化靜態全局數據(在編譯時)

#include <vector> 
using namespace std; 

static vector<vector<int> > STATIC_THING(4, vector<int>(4)); 

void Generator(int x, int y, vector<int> *output) { 
    // Heavy computing goes here 
    for(int i=0; i < 4; ++i) 
    (*output)[i] = x * y; 
    return; 
} 
static void FillThings() { 
    for(int x=0; x < 4; ++x) 
    for(int y=0; y < 4; ++y) 
     Generator(x, y, &STATIC_THING[x]); 
} 
FillThings(); 

int main() { 
} 

有沒有辦法比預先計算和我的硬編碼序列插入陣列,讓編譯器做這個升降其他?我覺得應該有一種方法,至少可以在第一個包含頭文件的頭文件中完成這個工作,但我只能在類中看到它。如果它能在編譯時促進計算,我可以使用數組而不是向量。

EDITS:

  • 雖然模板元編程建議,我的實際發電機算法過於複雜,借給自己這一技術。

  • 使用查找表似乎是我唯一的其他選項,可以讓我避免運行時計算;如果性能仍然是未來的問題,我會回頭看看。

+0

爲什麼不只是使用構造函數?而不是'STATIC_THINK',使用一個保存向量的對象。如果需要,您可以將其設置爲單例。 –

+0

我已經在傳遞過程中完成了這個工作,在構造函數中使用數據成員和初始化器創建一個靜態實例。我可以走這條路,但我更有興趣弄清楚爲什麼我不能像上面那樣完成這個任務,如果沒有其他的理由而不是學習新的東西。 – Ethereal

回答

4

這樣做:

static int FillThings() { 
    for(int x=0; x < 4; ++x) 
    for(int y=0; y < 4; ++y) 
    Generator(x, y, &STATIC_THING[x]); 
    return 9087; 
} 
static int q = FillThings(); 
+3

沒有必要。 'int q =(FillThings(),0);'應該這樣做。 –

+0

我喜歡這個解決方案,很明顯。爲什麼我不能直接調用這個函數,爲什麼編譯器不會以這種方式調用? @Kerrek,我之前沒有看到過這個符號,它的主要用途是什麼? – Ethereal

+0

這給了我未使用的變量警告,有沒有一種很好的方法來抑制這些警告? –

2

如果不能從實際的文字通過一撐初始化初始化,那麼你可以做這樣的事情:

typename std::vector<std::vector<int>> my_vector; 

static my_vector make_static_data() 
{ 
    my_vector result; 
    // ... populate ... 
    return result; 
} 

static const my_vector static_data = make_static_data(); 
+0

我唯一的問題是,在我的真實代碼中會有一個非常大的對象返回值。 – Ethereal

+1

@ethereal:爲什麼這是一個問題?幾乎肯定會有RVO,而且無論如何這都是在程序啓動時。 –

+0

重點:RVO,但我的一個擔心是完整的程序執行時間。我寧願不把優化放到編譯器上,只要我可以用最小的努力來確保它! – Ethereal

0

並不那麼容易: std :: vector是一個動態結構。它不是「可填寫的」或「編譯時間」。它可以在啓動時通過初始化一個靜態變量並返回一個調用的函數或lambda實際填充向量來填充。

this可以是一種方式。

但一個適當的「編譯時vecotr」應該像他的「指標」的模板是作爲參數的int,像

template<unsigned idx> 
struct THING 
{ 
    static const int value = .... //put a costant expression here 
}; 

用作THING<n>::value

「恆定表達」可以是一個function(THING<idx-1>::value),遞歸下降到專門

temnplate<> 
struct THING<0U> {}; 

即停止編譯器遞歸。

有,但是,一些限制:定義value靜態成員必須是constexpr(因此,僅整數類型,內置oerations和無<cmath>,並用constexpr聲明只是功能),並將該值表達用作idx必須本身是一個常量(不是變量)。

+0

這看起來比它更值得複雜。有沒有一種方法可以在編譯時使用數組而不是向量來計算? – Ethereal

+0

經過一番挖掘,我認爲你所建議的被稱爲「模板元編程」。我的代碼有點太冗長和複雜,不適合這種技術。 – Ethereal

+0

簡短回答:沒有。長答案:在編譯時沒有變量,只是整型常量和類型。你可以依靠對方來玩它們,但不能在編譯時分配給變量。初始化是一個運行時間活動。 –

相關問題