数组衰变为Lambda中的指针

时间:2015-08-20 04:27:21

标签: c++ arrays c++11 lambda

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。这是可能的,还是我必须使用函数,或将长度作为参数传递?

2 个答案:

答案 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。