[英]Why does std::map behave strangely when passed by value into a lambda?
[英]Why does the std::size on an array passed by value do not work?
為什么std::size()
不適用於按值傳遞的靜態分配數組?
void print_elemTab(int tab[])
{
// ...
int size = std::size(tab); //error
// ...
}
void test_tab()
{
const int TAB_SIZE = 5;
int tab[TAB_SIZE] = {};
// ...
cout << std::size(tab) << std::endl; //print 5
print_elemTab(tab);
// ...
}
我正在打印尺寸,然后我在print_elemTab()
中傳遞tab
,我再次使用std::size()
。
我沒有得到匹配的 function錯誤,所以我想知道為什么std::size()
第一次在test_tab()
而不是在print_elemTab()
我必須通過引用傳遞它嗎? 那么,除了任意長度的數組,我該怎么做呢?
還是因為我不知道的事情,我必須以另一種方式做到這一點?
我必須通過引用傳遞它嗎? 那么,除了任何長度的數組之外,我該怎么做呢?
是的,通過引用傳遞它是一種選擇。
template<std::size_t n>
void print_elemTab(int (&tab)[N]) // const int (&tab)[N], if the elements won't be modified
{
std::cout << N << "\n"; // where you can directly get the size `N`
}
或者像簡單的模板化 function 如下
template<typename T>
void print_elemTab(T& tab)// const T& tab, if the elements won't be modified
{
const auto size = std::size(tab);
std::cout << size << "\n";
}
另一種選擇是將數組推斷為其實際類型。 在您的情況下, tab
的類型為int[5]
。 如果您通過模板 function 完美轉發,編譯器可以推斷其實際類型(而不是衰減為指針)。
#include <iostream>
#include <array>
template<typename T>
void print_elemTab(T&& tab)
{
const auto size = std::size(tab); // now you can do std::size() on the int[size]
std::cout << size << "\n";
}
表達式中使用的數組指示符被隱式轉換(很少有例外,例如在sizeof
運算符中使用它們)為指向它們的第一個元素的指針。
所以在這個電話中
print_elemTab(tab);
參數表達式的類型為int *
。
另一方面,具有數組類型的function參數被編譯器調整為指向數組元素類型的指針。
例如,這些 function 聲明
void print_elemTab(int tab[]);
void print_elemTab(int tab[5]);
void print_elemTab(int tab[100]);
聲明相同的一個 function 並且等效於以下聲明
void print_elemTab(int *tab);
你甚至不能在你的程序中包含所有這些聲明,盡管編譯器會發出一條消息,指出存在冗余聲明。
因此,在 function 中,您正在處理int *
類型的指針。 並且sizeof( int * )
通常等於4
或8
,具體取決於所使用的系統。
如果您有這樣的聲明,您應該更改它,指定第二個參數,該參數將保留傳遞數組中的元素數量,例如
void print_elemTab(int *tab, size_t n );
function 可以這樣稱呼
print_elemTab(tab, std::size( tab ) );
另一種方法是通過引用傳遞數組。 在這種情況下,您應該聲明一個模板 function 例如
template <size_t N>
void print_elemTab( int ( &tab )[N] );
在 function 中,您可以直接使用模板參數N
作為數組中的元素數。 或者您可以將相同的標准 C++ function std::size
應用於數組。
或者 function 可以使用第二個模板類型參數進行更一般的聲明,例如
template <typename T, size_t N>
void print_elemTab( T ( &tab )[N] );
另一種方法是聲明 function 之類的
template <typename Container>
void print_elemTab( Container &container );
在這種情況下,您也可以將標准 function std::size
應用於參數容器。
是的,您必須通過引用傳遞它,因為它在傳遞給您的 function 時已衰減為指針。 並使 function 接受任何尺寸,我建議使用 function 模板,如下所示
#include <iostream>
template<size_t n>
void print_elemTab(int (&tab)[n])
{
int size = std::size(tab);
std::cout << size << "\n";// or just std::cout << n; and ignore the previous line
}
void test_tab() {
const int TAB_SIZE = 5;
int tab[TAB_SIZE] = {};
std::cout << std::size(tab) << std::endl; //print 5
print_elemTab(tab);
}
int main(){
test_tab();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.