[心得] sizeof_array
爬了之前的文章, 發現在算陣列元素個數的時候, 雖然使用 size-
of 是很方便~ 不過常會有指標錯用的情形! @_@
template<typename ElementType, size_t ARRAY_SIZE>
size_t sizeof_array( ElementType (&)[ ARRAY_SIZE ] )
{
return ARRAY_SIZE;
}
以上函式模板使用引數推導可以容易取得陣列大小, 雖然解決了這
個問題, 但是下面的程式碼 :
int iArray[] = { 1, 2, 3 };
bool bArray[ sizeof_array(iArray) ];
實際上 bArray是一個 VLA, gcc 加上選項 -Wvla 就會出現 :
[Warning] variable length array 'bArray' is used
這樣便無法將陣列以參考的形式傳遞給函式, 來減少參數的個數,
也不能給予特定元素初始值, 如果用來當作 std::array 的模板引
數, 也會出現下列訊息 :
'sizeof_array(ElementType (&)[ARRAY_SIZE])' cannot
appear in a constant-expression
因為這個版本的 sizeof_array 是執行時期才回傳值, 實用性顯得
低了些, 解決方案之一是在回傳值之前加上 constexpr關鍵字, 不
過因為 gcc還沒實作出這個功能, VC2010不支援, 所以還請各位看
我娓娓道來 > <, 另一個解決方案是使用類別模版, 非常簡單只有
12行 :
template <typename Type>
struct sizeof_array_impl
{
static_assert( std::is_array<Type>::value,
"this is not an array type" );
};
template <typename ElementType, size_t ARRAY_SIZE>
struct sizeof_array_impl<ElementType[ARRAY_SIZE]>
{
enum { value = ARRAY_SIZE };
};
為陣列型態提供特化版本, 列舉值 value即是陣列大小, 如果給錯
型態將會具現化泛化的版本, 造成確保失敗, 編譯停止輸出訊息.
#define sizeof_array( array )\
sizeof_array_impl<decltype(array)>::value
巨集中搭配decltype關鍵字取得物件的型態, 陣列大小得以在編譯
時期被評估.
以上是小弟淺見, 如有 OP 會自 D, 謝謝觀賞!
--
╭───╮ ╭╮ ╭╮ ☆
非常非常善良的你 │╭──╯ ☆ ││ ││ ☆
非常愛我的你 │╰──╮╭──╮│╰──╯│╭──╮╭──╮╭──╮
────────── ╰──╮││╭╮│╰─╮╭─╯│ ‧ ││╭╮││╭╮│
曾一瞬間展露笑容的你 ╭──╯││╰╯│ ││ │ ─╯│╰╯│││││
曾接受我心意的你 ╰───╯╰──╯ ☆ ╰╯ ╰──╯╰──╯╰╯╰╯
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.121.197.115
推
09/12 12:52, , 1F
09/12 12:52, 1F
→
09/12 12:53, , 2F
09/12 12:53, 2F
→
09/12 12:53, , 3F
09/12 12:53, 3F
→
09/12 12:54, , 4F
09/12 12:54, 4F
→
09/12 12:54, , 5F
09/12 12:54, 5F
→
09/12 13:28, , 6F
09/12 13:28, 6F
→
09/12 13:28, , 7F
09/12 13:28, 7F
→
09/12 13:28, , 8F
09/12 13:28, 8F
※ 編輯: loveme00835 來自: 114.45.64.97 (09/12 13:50)
推
09/12 14:05, , 9F
09/12 14:05, 9F
推
09/12 15:24, , 10F
09/12 15:24, 10F
→
09/12 17:59, , 11F
09/12 17:59, 11F
推
09/13 00:00, , 12F
09/13 00:00, 12F
→
09/13 00:14, , 13F
09/13 00:14, 13F
※ 編輯: loveme00835 來自: 140.121.197.115 (09/13 00:19)
→
09/13 07:11, , 14F
09/13 07:11, 14F
→
09/13 09:54, , 15F
09/13 09:54, 15F
推
09/13 10:59, , 16F
09/13 10:59, 16F
→
09/13 10:59, , 17F
09/13 10:59, 17F
→
09/13 11:00, , 18F
09/13 11:00, 18F
→
09/13 17:20, , 19F
09/13 17:20, 19F
推
09/13 20:54, , 20F
09/13 20:54, 20F
→
09/13 20:54, , 21F
09/13 20:54, 21F
→
09/13 20:54, , 22F
09/13 20:54, 22F
int a[ 10 ];
cout << sizeof_array( a ) << endl; // 使用第一版本
編譯器看到這樣的code會由模版產生類似下面的函式實體出來
size_t sizeof_array( int (&)[ 10 ] )
{
return 10;
}
雖然數值可以在編譯時期被得知, 但是在使用的時候必須要先呼叫
函式才能拿回這個常數, 要到執行時才能知道陣列大小.
※ 編輯: loveme00835 來自: 140.121.197.115 (09/13 21:18)
推
09/13 21:45, , 23F
09/13 21:45, 23F
→
09/13 21:46, , 24F
09/13 21:46, 24F
→
09/13 21:46, , 25F
09/13 21:46, 25F
→
09/13 23:19, , 26F
09/13 23:19, 26F
→
09/13 23:20, , 27F
09/13 23:20, 27F
→
09/13 23:21, , 28F
09/13 23:21, 28F
→
09/13 23:21, , 29F
09/13 23:21, 29F
→
09/13 23:22, , 30F
09/13 23:22, 30F
→
09/13 23:22, , 31F
09/13 23:22, 31F
推
09/14 00:40, , 32F
09/14 00:40, 32F