簡體   English   中英

不知道C++中這段代碼是什么意思

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM