2014-01-29 29 views
4

好吧,所以我試圖在編譯時通過初始化一堆constexpr static int const數組來做一些巧妙的事情。即使運行時性能完全不受初始化這些陣列的控制,它似乎是一個有趣的小練習。我寫了一個測試,安裝,看它是否是可能的,而我最終能夠做到這一點:當編譯時初始化靜態數組時,g ++(4.7.2)的缺陷或特性?

struct Test 
{ 
    constexpr static int const array[10] = Array<int, 10, 0, Increment>::array; 
}; 

constexpr int const Test::array[10]; 

int main() 
{ 
    cout << Test::array[3] << '\n'; 
} 

這裏,Array有一個靜態成員稱爲array其中包含10個int S,從0開始,在那裏每個後續元素的值由稱爲Increment(即{0, 1, ..., 9})的模板 - 元編程函數來確定。如預期的那樣,該程序打印出號碼3

太棒了吧?我現在可以只編寫函數,並在編譯時初始化數組中的各種時髦模式。下一步:未硬編碼的陣列尺寸10通過使Test一個類模板,如下所示:

test.cc:43:72: error: array must be initialized with a brace-enclosed initializer 

template <size_t Size> 
struct Test 
{ 
    constexpr static int const array[Size] = Array<int, Size, 0, Increment>::array; 
}; 

template <size_t Size> 
constexpr int const Test<Size>::array[Size]; 

int main() 
{ 
    cout << Test<10>::array[3] << '\n'; 
} 

然而,一下子現在不與消息編譯

這是爲什麼發生?是否有這樣的原因,一旦我將該類變成類模板,或者我偶然發現了GCC中未實現的/錯誤的東西,這種初始化就失效了?我可以根據請求發佈我的其餘代碼(例如執行Array)。現在我認爲這應該夠了。

編輯錯誤可以用不同的,瑣碎的,執行的Array轉載節省一些空間,在這裏:

template <size_t Size> 
struct Array 
{ 
    constexpr static int const array[Size] = {}; 
}; 

template <size_t Size> 
struct Test 
{ 
    constexpr static int const array[Size] = Array<Size>::array; 
}; 
+0

嘗試一個更新的gcc(ideone.com有4.8在線)。我無法用4.8重現錯誤。 –

+0

@ n.m。它在C++ 11上給出了同樣的錯誤,我不知道如何將--std = C++ 11傳遞給它們的4.8.1編譯器...... – JorenHeit

+0

@JorenHeit它們有一個C++ 11模式和一個常規的C++模式。你也可以嘗試Coliru。 – 2014-01-29 15:52:48

回答

4

以下是非法的;

static const int a[10] = {}; 
static const int b[10] = a; // Illegal 

所以gcc的bug實際上是針對非模板的情況。您可以使用std::array代替C數組。

+0

即使將'a'和'b'聲明爲'constexpr'? – JorenHeit

+0

@JorenHeit:是的。 – Jarod42

+0

謝謝!我將所有的C數組轉換爲'std :: array's,當然,使用雙括號初始化它,現在它可以工作:-)謝謝你。 – JorenHeit