数组衰变为Lambda中的指针

Ceb*_*zre 3 c++ arrays lambda c++11

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;
}
Run Code Online (Sandbox Code Playgroud)

此代码提供以下输出:

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;
                                                                     ^
Run Code Online (Sandbox Code Playgroud)

我想停止int const arr[]腐烂成指针.如果我使用引用,它需要一个模板来获取大小,就像arraySize一样.模板不适用于lambdas.这是可能的,还是我必须使用函数,或将长度作为参数传递?

M.M*_*M.M 5

这不会腐烂.衰减是指将数组类型的表达式转换为指针.

函数参数列表中的东西不是表达式; 他们是声明者.在这种情况下,数组声明符被调整为指针声明符,例如:

void f(int const arr[]);
Run Code Online (Sandbox Code Playgroud)

相当于:

void f(int const *arr);
Run Code Online (Sandbox Code Playgroud)

Lambda也不例外; lambda函数的行为类似于保存捕获变量的自定义类的成员函数.


您可以通过引用传递数组,以避免此调整:

auto const lambda = [](int const (&arr)[size]) -> void
Run Code Online (Sandbox Code Playgroud)

使用C++ 14泛型lambdas,此选项也通过引用接收数组:

auto const lambda = [](auto& arr) -> void
Run Code Online (Sandbox Code Playgroud)

在后一种情况下,const由于参考折叠也推断出.

据我所知,不可能让lambda 接受一个数组,但仍然推断出数组大小.