template <typename T, size_t N>
char (&ArraySizeHelper(T (&array)[N]))[N];
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
T (&array)[N]:函式參數為陣列引用,編譯器能推導出類型 T 與大小 Nchar (&)[N]:字元陣列引用,大小同樣為 Nsizeof(ArraySizeHelper(array)):對引用取 sizeof 得到被引用物件大小,即 sizeof(char[N]) = N整個過程在編譯期完成,零執行期開銷。
#define arraysize(array) (sizeof(array)/sizeof(array[0]))
傳統寫法雖簡單,但無法防止指標退化:若傳入指標而非陣列,sizeof(pointer)/sizeof(pointer[0]) 會得到錯誤結果(通常為 1 或 4/8)。Chrome 的模板版本只接受陣列引用,傳入指標會編譯失敗,從源頭杜絕誤用。
double a[200];
double* b = new double[100];
int cnt1 = arraysize(a); // 200 ✓
// int cnt2 = arraysize(b); // 編譯錯誤:無法推導 N
new T[n])、函式參數退化為指標的情況C++17 起可用 std::size(arr)(<iterator>),同樣編譯期計算、拒絕指標、支援所有容器,為標準化解法。