按照斯科特·迈耶(Scott Meyer)的“现代C++”中的一个示例,我将利用模板来减少std::array
的大小。我偶然尝试编译myUsage
函数用法。
#include <array>
#include <iostream>
template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (&) [N]) noexcept
{
return N;
}
void scottUsage()
{
int b[5];
std::array<short, arraySize(b)> c;
std::cout << arraySize(b) << " = " << c.size() << "\n";
}
template <typename T, std::size_t N>
void myUsage(T & arr [N])
{
for (auto i=0; i<arraySize(arr); i++)
std::cout << arr[i] << "\t";
}
int main()
{
scottUsage();
int a[7];
myUsage(a);
}
因此出现两个问题:
(&)
的作用是什么?删除会触发error: creating array of references
,似乎是禁止的myUsage
签名出了什么问题? 最佳答案
myUsage()
需要使用T (&arr) [N]
。
template <typename T, std::size_t N>
void myUsage(T (&arr) [N])
括号告诉编译器该引用适用于数组本身,而不适用于数组的元素类型。
另外,
arraySize()
和myUsage()
都应引用const
数据:template <typename T, std::size_t N>
constexpr std::size_t arraySize(const T (&) [N]) noexcept
...
template <typename T, std::size_t N>
void myUsage(const T (&arr) [N])
顺便说一句,从C++ 17开始不需要
arraySize()
,请改用 std::size()
:#include <array>
#include <iostream>
#include <iterator>
void scottUsage()
{
int b[5];
std::array<short, std::size(b)> c;
std::cout << std::size(b) << " = " << c.size() << "\n";
}
template <typename T, std::size_t N>
void myUsage(const T (&arr) [N])
{
for (auto i = 0; i < std::size(arr); ++i)
std::cout << arr[i] << "\t";
/* better:
for (const T &value : arr)
std::cout << value << "\t";
*/
}
int main()
{
scottUsage();
int a[7];
myUsage(a);
}