3 回答

TA貢獻1911條經驗 獲得超7個贊
首先讓我們剖析參數T(&)[size]。首先從內到外,從右到左,從括號組中讀取聲明:這是一個未命名的參數,是size對type類型的數組的引用T。
也就是說,它接受對任何數組的引用,其中數組的類型和大小是模板參數。
如果我們這樣稱呼它:
int a[10];
GetArrLength(a);
編譯器將嘗試推斷模板參數。為了使參數類型與您要傳遞的參數相匹配,T必須為int并且size必須為10(使參數成為對10 ints 數組的引用)。
然后,您返回該大小,從而獲得數組中元素的數量。
此代碼有兩個“問題”。首先,大小不能為負,因此使用帶符號類型作為模板參數和返回類型沒有意義。而是應使用無符號類型。最好是std::size_t:
template<typename T, std::size_t Size>
std::size_t GetArrLength(T(&)[Size]) { return size; }
第二個問題是,即使數組的大小是多少,此函數的結果也不是常量表達式。雖然在大多數情況下都可以,但是如果我們可以從中獲得一個常量表達式,那就更好了。那就是您得到此解決方案的地方:
template <std::size_t N>
struct type_of_size
{
typedef char type[N];
};
template <typename T, std::size_t Size>
typename type_of_size<Size>::type& sizeof_array_helper(T(&)[Size]);
#define sizeof_array(pArray) sizeof(sizeof_array_helper(pArray))
這樣使用:
int a[10];
const std::size_t n = sizeof_array(a); // constant-expression!
它通過三件事起作用:第一是與上面相同的想法,模板參數將被填充以提供數組的大小。
第二部分是使用該信息來創建具有特定大小的類型,從而成為一個type_of_size輔助對象。該部分不是嚴格必需的,但我認為它使代碼更易于閱讀。A char[N]的大小N始終等于,因此我們可以濫用它來“存儲”數組的大小……以類型本身的大小!
第三部分是使用來獲得該大小sizeof。它實際上不評估任何東西,因此我們不需要為函數定義。它只是說:“如果要這樣做,大小將是……”。大小是char數組中“存儲”的大小。

TA貢獻1817條經驗 獲得超14個贊
您可以犧牲可讀性來跳過最后一個版本中的樣板代碼,但是我將其寫為@Matthew Flaschen和@BobAlmond的練習:) template <typename T, size_t size> char (&sizeof_array_helper( T (&)[size]))[size];-宏將保留原樣。

TA貢獻1886條經驗 獲得超2個贊
使用C ++ 11時constexpr
,“ return n;” 函數成為編譯時間常數!template <typename T, size_t n> constexpr size_t array_size(const T (&)[n]) { return n; }
- 3 回答
- 0 關注
- 368 瀏覽
添加回答
舉報