2013-06-25 62 views
2

有這個作業問題,我一直在破壞我的大腦:在C++編譯時安全數組?

我必須在C++中創建一個數組類,其中在編譯時檢查數組元素的索引訪問,即如果我嘗試要訪問具有超出ita大小的索引的數組,將導致編譯錯誤。

我以爲我會使用枚舉作爲索引而不是整數,但我與我的導師說話,他告訴我,這不是正確的方式,他還說,「認爲對於同樣的價格,你可以用它來有一個索引不從0開始的數組「或類似的東西。

我會很感激任何建議!

+5

在使用變量進行索引編制的地方,您不可能報告這樣的錯誤,因爲很可能只有在運行時才能知道它的值。 –

回答

5

這裏是一個提示:如果您想查詢在編譯的時候,你基本上只能有一個選擇:你需要使用非類型模板參數。

標準庫類型std::tuple實現他,所以檢查瞭解如何解決這個問題的靈感。

+0

一般來說,你的第一句話不是真的 - 你也可以使用帶有constexpr值的static_assert。 –

+0

@ sasha.sochka當然。我在運行時調用函數並*將參數*傳入它的上下文中寫道。如果允許函數參數,'constexpr'將會工作。 –

+0

這是允許的。簡單的例子:'constexpr int sqr(int val){return val * val; } int arr [sqr(3)];' –

1

提示,也許措詞有點不同:如果你想在編譯時檢查索引,它的值也必須在編譯時知道。現在,如何將某個函數傳遞給編譯時間

要在編譯時發出錯誤信號,static_assert可以很容易地使用。

0

您可能有機會使用自定義類作爲索引類型。然後,您可以通過限制類的運算符來限制索引元素的生成。特別是,這可以確保沒有用戶輸入可以用作索引(如果你沒有提供任何方法來將整數(或類似的)轉換爲索引類型),如果你允許的話,你根本就沒有機會!)。

+0

我認爲這是他這意味着,但我不知道如何創建一個有限世代的類(編譯器知道的某個編號?) 這是來自演講幻燈片的引用:「數組引用:不可能檢測到溢出數組索引 索引類型爲整數時不可能 - 如果 索引的類型對應於數組大小(它必須是數組的 類型的一部分)。 – dog

+0

來自演講幻燈片的引用讓我想到了一個假設,即可以預期模板驅動的解決方案(就像@sasha_sochka指出的那樣)。 – urzeit

6

std::array來自C++ 11正是你所要求的。它與已知大小的編譯時,這允許編譯時間檢查陣列外的邊界錯誤

實施例:

std::array<int, 5> arr = {1, 2, 3, 4, 5}; 
std::get<3>(arr); // returns 4; 
std::get<9>(arr); // COMPILE ERROR 

內部此陣列使用模板陣列的大小(如從例子中看到的實施,第一行中的第二個模板參數)和static_assert,它會爲您的條件執行編譯時檢查(在這種情況下,它將是index < array_size)。同樣如你在例子中看到的,你使用std :: get而不是operator [],因爲它再次使用模板參數作爲索引,它必須是一個常量表達式(constexpr),以允許編譯時檢查而不是run-時間。

如果你需要一個變量索引,你可以使用舊的好運算符[],但是你不會有編譯時超出邊界的檢查,這根本不可能完成。

+0

不錯,但並沒有真正解釋如何創建這樣的類。 –

+0

我加了一點點解釋 –

+0

謝謝!但我敢肯定,因爲它幾乎完全是我預料之中的事我自己 – dog