[英]I don't know the meaning of this piece of code in C++
我想知道為什么這種代碼可以得到測試數組的大小? 我不熟悉模板中的語法。 也許有人可以解釋“模板”下代碼的含義。 此外,參考鏈接也是首選。 謝謝!
#define dimof(array) (sizeof(DimofSizeHelper(array)))
template <typename T, size_t N>
char(&DimofSizeHelper(T(&array)[N]))[N];
void InitDynCalls()
{
char test[20];
size_t n = dimof(test);
printf("%d", n);
}
template <typename T, size_t N>
char(&DimofSizeHelper(T(&array)[N]))[N];
// see it like this:
// char(&DimofSizeHelper(T(&array)[N]))[N];
// template name: DimofSizeHelper
// param name: array
// param type: T(& )[N])
// return type: char(& )[N];
DimofSizeHelper
是一個模板 function,它采用T(&)[N]
參數 - 也就是對T
類型的 N 個元素的 C 數組的引用,並返回一個char (&)[N]
也就是對 N 個字符數組的引用. 在 C++ 中,char 是變相的字節,並且sizeof(char)
按照標准保證為1
。
size_t n = dimof(test);
// macro expansion:
size_t n = sizeof(DimofSizeHelper(array));
n
被分配了DimofSizeHelper
返回類型的大小,即sizeof(char[N])
,即N
。
這有點令人費解和不必要的 . 通常的做法是:
template <class T, size_t N>
/*constexpr*/ size_t sizeof_array(T (&)[N]) { return N; }
由於 C++17 這也是不必要的,因為我們有std::size
這樣做,但以更通用的方式,能夠獲得任何 stl 樣式容器的大小。
正如 BoBTFish 所指出的,邊緣情況是必要的。
這實際上很難解釋,但我會給它一個 go ......
首先, dimof
告訴您維度或數組中元素的數量。 (我相信“維度”是 Windows 編程環境中的首選術語)。
這是必要的,因為C++
和C
沒有為您提供確定數組大小的本地方法。
人們通常認為sizeof(myArray)
會起作用,但這實際上會給你 memory 的大小,而不是元素的數量。 每個元素可能占用超過 1 個字節的內存!
接下來,他們可能會嘗試sizeof(myArray) / sizeof(myArray[0])
。 這將給出數組 memory 中的大小除以第一個元素的大小。 沒關系,廣泛用於C
代碼。 這樣做的主要問題是,如果您傳遞指針而不是數組,它似乎會起作用。 memory 中的指針大小通常為 4 或 8 個字節,即使它指向的對象可能是一個包含 1000 個元素的數組。
因此,在C++
中嘗試的下一件事是使用模板來強制執行僅適用於 arrays 的內容,並且會在指針上給出編譯器錯誤。 它看起來像這樣:
template <typename T, std::size_t N>
std::size_t ArraySize(T (&inputArray)[N])
{
return N;
}
//...
float x[7];
cout << ArraySize(x); // prints "7"
該模板僅適用於數組。 它將推斷類型(不是真正需要,但必須在那里才能使模板工作)和數組的大小,然后返回大小。 模板的編寫方式不可能使用指針。
通常你可以在這里停下來,這是在 C++ 標准庫中作為std::size
。
這很酷,但在一個模糊的邊緣情況下仍然失敗:
struct Placeholder {
static float x[8];
};
template <typename T, int N>
int ArraySize (T (&)[N])
{
return N;
}
int main()
{
return ArraySize(Placeholder::x);
}
請注意,數組x
已聲明,但未定義。 要使用它調用 function (即ArraySize
),必須定義x
。
In function `main':
SO.cpp:(.text+0x5): undefined reference to `Placeholder::x'
collect2: error: ld returned 1 exit status
你不能鏈接這個。
您在問題中的代碼是一種解決方法。 我們沒有實際調用 function,而是聲明了一個 function,它返回一個大小正好合適的 object 。 然后我們使用sizeof
技巧。
看起來我們調用了 function,但sizeof
純粹是一個編譯時構造,所以 function 從未真正被調用過。
template <typename T, size_t N>
char(&DimofSizeHelper(T(&array)[N]))[N];
^^^^ ^ ^^^
// a function that returns a reference to array of N chars - the size of this array in memory will be exactly N bytes
請注意,您實際上不能從 function 返回數組,但您可以返回對數組的引用。
那么DimofSizeHelper(myArray)
是一個表達式,其類型是N
char
上的數組。 該表達式實際上不必是可運行的,但在編譯時它是有意義的。
因此sizeof(DimofSizeHelper(myArray))
將在編譯時告訴您如果您確實調用了 function 會得到什么大小。 盡管我們實際上並沒有調用它。
如果最后一個塊沒有任何意義,請不要擔心。 解決一個奇怪的邊緣案例是一個奇怪的技巧。 這就是為什么你不自己編寫這種代碼,讓庫實現者擔心這種廢話。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.