有這個作業問題,我一直在破壞我的大腦:在C++編譯時安全數組?
我必須在C++中創建一個數組類,其中在編譯時檢查數組元素的索引訪問,即如果我嘗試要訪問具有超出ita大小的索引的數組,將導致編譯錯誤。
我以爲我會使用枚舉作爲索引而不是整數,但我與我的導師說話,他告訴我,這不是正確的方式,他還說,「認爲對於同樣的價格,你可以用它來有一個索引不從0開始的數組「或類似的東西。
我會很感激任何建議!
有這個作業問題,我一直在破壞我的大腦:在C++編譯時安全數組?
我必須在C++中創建一個數組類,其中在編譯時檢查數組元素的索引訪問,即如果我嘗試要訪問具有超出ita大小的索引的數組,將導致編譯錯誤。
我以爲我會使用枚舉作爲索引而不是整數,但我與我的導師說話,他告訴我,這不是正確的方式,他還說,「認爲對於同樣的價格,你可以用它來有一個索引不從0開始的數組「或類似的東西。
我會很感激任何建議!
這裏是一個提示:如果您想查詢值在編譯的時候,你基本上只能有一個選擇:你需要使用非類型模板參數。
標準庫類型std::tuple
實現他,所以檢查瞭解如何解決這個問題的靈感。
一般來說,你的第一句話不是真的 - 你也可以使用帶有constexpr值的static_assert。 –
@ sasha.sochka當然。我在運行時調用函數並*將參數*傳入它的上下文中寫道。如果允許函數參數,'constexpr'將會工作。 –
這是允許的。簡單的例子:'constexpr int sqr(int val){return val * val; } int arr [sqr(3)];' –
提示,也許措詞有點不同:如果你想在編譯時檢查索引,它的值也必須在編譯時知道。現在,如何將某個函數傳遞給編譯時間?
要在編譯時發出錯誤信號,static_assert
可以很容易地使用。
您可能有機會使用自定義類作爲索引類型。然後,您可以通過限制類的運算符來限制索引元素的生成。特別是,這可以確保沒有用戶輸入可以用作索引(如果你沒有提供任何方法來將整數(或類似的)轉換爲索引類型),如果你允許的話,你根本就沒有機會!)。
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-時間。
如果你需要一個變量索引,你可以使用舊的好運算符[],但是你不會有編譯時超出邊界的檢查,這根本不可能完成。
在使用變量進行索引編制的地方,您不可能報告這樣的錯誤,因爲很可能只有在運行時才能知道它的值。 –