template<std::size_t size>
constexpr std::size_t arraySize(int const (&)[size])
{
return size;
}
int main()
{
auto const lambda = [](int const arr[]) -> void
{
std::cout << "The length of the array is: " << arraySize(arr) << std::endl;
};
lambda({1, 2, 3});
return 0;
}
此代码提供以下输出:
main.cpp: In lambda function:
main.cpp:23:69: error: no matching function for call to 'arraySize(const int*&)'
std::cout << "The length of the array is: " << arraySize(arr) << std::endl;
^
main.cpp:12:23: note: candidate: template<long long unsigned int size> constexpr std::size_t arraySize(const int (&)[size])
constexpr std::size_t arraySize(int const (&)[size])
^
main.cpp:12:23: note: template argument deduction/substitution failed:
main.cpp:23:69: note: mismatched types 'const int [size]' and 'const int*'
std::cout << "The length of the array is: " << arraySize(arr) << std::endl;
^
我想阻止int const arr[]
腐烂成指针。如果我使用引用,它需要一个模板来获取大小,就像arraySize一样。模板不适用于lambdas。这是可能的,还是我必须使用函数,或将长度作为参数传递?
答案 0 :(得分:5)
这不是腐烂。衰减是指将数组类型的表达式转换为指针。
函数参数列表中的内容不是表达式;他们是声明者。在这种情况下,数组声明符被调整成为指针声明符,例如:
void f(int const arr[]);
相当于:
void f(int const *arr);
Lambdas也不例外; lambda函数的行为类似于保存捕获变量的自定义类的成员函数。
您可以通过引用传递数组,以避免此调整:
auto const lambda = [](int const (&arr)[size]) -> void
使用C ++ 14通用lambdas,此选项也通过引用接收数组:
auto const lambda = [](auto& arr) -> void
在后一种情况下,由于参考折叠,也推导出const
。
据我所知,不可能让lambda 仅接受一个数组,但仍然推断出数组大小。
答案 1 :(得分:0)
根据您希望使用多少种不同类型的阵列大小,您可能需要不同的解决方案。
如果你需要它的数组大小在编译时是已知的,我要考虑的一件事是使用std :: array,即创建一个模板函数,它生成一个适当的lambda函数,它取{{1特定大小的。并将该lambda函数与该大小的数组一起使用。
如果在编译时不知道可能数组的大小,那么我想我会建议将std::array
传递给lambda。