2013-04-14 91 views
1

我已經實現了使用查找表的快速比較功能。由於該功能在項目中的多個類中使用,因此我需要確保在整個程序執行期間只有一個查找表副本。在C++中使用全局矢量

查找表是一個簡單的vector<int>大小爲65536.我希望這個表在程序的開始時被初始化,而不是在第一次使用的時候初始化。如何處理這個問題?

以下代碼片段是我比較函數的當前版本。我相信通過使lookup_table成爲一個靜態變量,問題將僅部分解決,因爲靜態變量的生命週期在程序流第一次遇到聲明時開始。

int fast_compare(const char* array1, const char* array2, int length) 
{ 
    static const vector<int> lookup_table = init_lookup_table(); 

    // process the input arrays... 
    // ... 
    return lookup_table[...]; 
} 

vector<int> init_lookup_table() 
{ 
    vector<int> lut(65536); 

    // ---------------------------- 
    // initialize the look-up table 
    // ... 
    // ... 
    // end of initialization 
    // ---------------------------- 

    return lut; 
} 
+1

解釋的。如果你知道在編譯時的大小,您可以受益於使用'的std :: array',而不是'的std :: VECTOR'。 –

+1

在'fast_compare'函數中聲明'lut'作爲'static'變量會使它更加線程安全。如果您需要可預測的運行時,則可以在啓動時通過調用函數來初始化變量。 –

+0

我對thread-safty的評論僅適用於C++ 11,請參見第6.7.4節。 –

回答

2

你描述的是辛格爾頓模式。網上有關於如何使用C++實現單例的文檔。

基本上它是一個小型類,它承載一個靜態函數,它返回指向查找表的指針/引用(我個人更喜歡引用)。

參考:Singleton: How should it be used

然而,一個更簡單的解決您的具體問題可能是剛纔生成的查找表一次,然後繞手boost::shared_pointer秒。

+0

好的,但如何確保查找表在使用之前分配?如果這個表非常大,那麼對fast_compare()函數的第一次調用可能會執行得很慢,因爲表將在程序流第一次遇到聲明時分配。我希望表比第一次調用'fast_compare()'更早分配。 – enzom83

+1

您可以始終在一開始執行單個查詢,而不使用該查詢的結果。或者你可以嘗試一個靜態類變量。 – ypnos

5

我希望這個表格在程序開始時被初始化,而不是在它第一次使用的時候初始化。

爲什麼不在cpp文件中使用未命名的命名空間?

#include <numeric> 
#include <iterator> 
#include <iostream> 
#include <vector> 

namespace { 
    //c++11 version 
    static auto const lookup_table = []() -> std::vector<int> { 
     std::vector<int> lut(65536); 
     iota(begin(lut), end(lut), 0);// init lut here 
     return lut; 
    }();// invoke the lambda 

    //c++ 98 version 
    //static const std::vector<int> lookup_table = init_lookup_table(); 
} 

int main() 
{ 
    std::cout<<"lut[32768] = " << lookup_table[32768]<<std::endl; 
} 

拉姆達初始化是由香草薩特here

+0

好現代的東西。我不明白狗屎,承認。 – ypnos

+1

@ypnos我已經添加了一個C++ 98版本。 lambda的好處是你沒有* named *函數,而只是一個與全局相關的初始化代碼塊。 –