![](/img/trans.png)
[英]Passing array by reference without explicitly stating the size of the array in function declaration
[英]Passing an array to function without explicit array size
我是 C++ 的新手,關於將 arrays 傳遞給 function (可能是同一件事),我有 2 個問題。
通過引用將數組傳遞給 function 時,參數是否不需要顯式大小信息,如void my_func (const T &array)
而不是void my_func (const T (&array)[10])
?
具有數組指針參數void my_func (const T* array)
和void my_func (const T(* array)[10])
(有或沒有明確的數組大小)的 function 有什么區別?
下面是在不顯式傳遞數組大小的情況下接受任何大小的數組的代碼:
template<typename _Ret, //return type
typename _Coll> //collection type, no size argument
_Ret Sum(const _Coll& c) {
_Ret sum = 0;
for (auto& v : c)
sum += v;
return sum;
}
int main() {
// With regular array, Passed as reference
int arr[] = {1, 2, 3, 4, 5};
std::cout << Sum<int64_t>(arr) << "\n"; //15
// With vector
std::vector<int> vec = {1, 2, 3, 4, 5};
std::cout << Sum<int64_t>(vec) << "\n"; //15
return 0;
}
此示例源自的文章如下所述:
此外,模板的使用甚至可以避免難看的數組引用語法,並使代碼適用於任何數組大小。
如果這可行,那么以下任何數組大小的通用模板是否不必要?
template<typename T, std::size_t S>
void my_func(T (&arr)[S]) {
... ...;
}
還有一個附帶問題,為什么template<typename _Ret, typename _Coll>
需要 2 個模板 arguments 但Sum<int64_t>(arr)
只指定 1 個模板參數?
- 通過引用將數組傳遞給 function 時,參數是否不需要顯式大小信息,如 void my_func (const T &array) 而不是 void my_func (const T (&array)[10])?
引用參數不一定必須是對數組的引用。
const T &
是對const T
的引用。 例如,如果T
類型別名為int[10]
,則const T &
為const int (&)[10]
即引用 10 const int
的數組。 如果T
是模板類型參數,那么模板可以被實例化為不同的類型,包括不同大小的數組類型,也包括非數組類型。
const T (&)[10]
是對 10 個const T
數組的引用。
當大小信息被編碼在參數的類型中時,您不需要單獨傳遞大小信息,例如參數是對數組的引用時的情況。
但是我的問題中的示例既沒有定義別名
你錯了。 您的示例是模板 function,模板類型參數是類型別名。
Function 調用語句只是將 arr 轉換(衰減)為指向 int 的指針。
你錯了。 當引用綁定到它時, arr
不會衰減為指向 int 的指針。 數組衰減發生在左值到右值的轉換上。 將引用綁定到 object 時,沒有此類轉換。
- 具有數組指針參數 void my_func (const T* array) 和 void my_func (const T(* array)[10])(帶或不帶顯式數組大小)新版本的 function 有什么區別?
const T*
是指向const T
的指針。
const T(*)[10]
是指向const T[10]
的指針,即指向 10 T
數組的指針。 例如,如果T
是int
的別名,則前者為const int*
,后者為const int(*)[10]
。
注意,如果T
是一個數組,那么前者也可以是一個指向數組的指針。 例如,如果T
是int[42]
,那么前者是const int(*)[42]
即指向 42 個const int
數組的指針,而后者是const int(*)[42][10]
即指向一個42 個const int
的 10 個 arrays 的數組。
...和 void my_func (const T* array[10])(有或沒有明確的數組大小)舊版本?
const T* array[10]
是一個包含 10 個指向const T
的指針的數組。 但是,function 參數絕不是 C++ 中的數組。 如果使用數組參數聲明 function,則將該參數調整為指向該數組元素的指針。 指向 const T 的 10 個指針數組的元素是指向const T
const T
的指針,即const T*
,指向此類 object 的指針是const T**
。 因此,這個參數實際上是const T**
。
const T*
和const T**
之間的區別在於后者是指向前者的指針。
如果這可行,那么以下任何數組大小的通用模板是否不必要?
這取決於。 如果您不需要它,那么您的用例就不需要它。
但這並不意味着它完全沒有必要。 For example, if you need a function overload that accepts only arrays, then you cannot use a T&
parameter which can accept arguments that are not arrays.
為什么
template<typename _Ret, typename _Coll>
需要 2 個模板 arguments
因為T (&arr)[S]
S
的 S 必須是模板值參數,才能將引用綁定到任何大小的 arrays。 如果您使用諸如T (&arr)[10]
之類的非變量常量,那么您只能接受一種大小的 arrays。
但是
Sum<int64_t>(arr)
僅指定 1 個模板參數?
這個不使用對S
元素數組的引用,因此不需要模板值參數S
。
_Ret
和_Coll
名稱保留給語言實現。 通過將這些名稱定義為模板參數,程序的行為將是未定義的。 不要定義保留名稱。 您應該為模板參數選擇其他名稱。
T
不是一個數組, void my_func (const T &array)
不會是嘗試的正確方法,因為它需要一個對T
的引用,而不是一個數組。 測試這個的正確方法可能是void my_func(const T (&array)[])
:#include <iostream>
void my_func(const int (&)[]) {}
int main()
{
int a = 10;
int b[] = {1, 2, 3};
my_func(b);
return 0;
}
當我嘗試運行它時,我收到一個錯誤: error: parameter '<anonymous>' includes reference to array of unknown bound 'const int []'
。 用const int (&)[3]
替換const int (&)[]
] 使其工作。 所以不,你必須指定數組的大小。
void my_func(const T *array)
等價於void my_func(const T array[])
而void my_func(const T (*array)[10])
等價於void my_func(const T array[][10])
。 C++ Insights是查看模板如何擴展的好地方。 當我們執行Sum<int64_t>(arr)
時, Sum
的新 function 將從int64_t Sum<int64_t, int [5]>(int const (&c)[5])
模板創建。 如您所見,您現在不必指定尺寸,因為模板會為您完成。 每次將不同大小的數組傳遞給Sum
時,都會創建一個新的 function 以使用該大小。
還有一個附帶問題,
template<typename _Ret, typename _Coll>
需要 2 個模板 arguments 但為什么does Sum<int64_t>(arr)
只指定 1 個模板參數?
因為推導出了第二個參數。 由於編譯器知道您將int [5]
傳遞給 function,因此您無需傳遞類型。 但是,它無法知道返回類型,因此您必須傳遞它的類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.