为什么这个模板函数不能识别 lamda 的返回类型?

why this template function does not recognize the lamda's returned type?

此模板函数无法识别 lamda 的返回类型,甚至将其指定为反注释 '->void'。

为什么会这样?

我该怎么做才能避免这个问题?

#include<iostream>
#include<array>
template<typename T, typename S, size_t SIZE>
void for_each(std::array<T,SIZE>& arr, S(*func)(int&))
{
    for (auto i{0}; i != arr.size(); ++i)
        func(arr[i]);
}
int main()
{
    std::array<int, 5> five_elems{10, 20, 30, 40, 50};
    for_each(five_elems, [](int& ref)/*->void*/{ref *= 2; std::cout << ref << ' '; });
    //for (auto i : five_elems)
    //    i*=2;
    for (const auto i : five_elems)
        std::cout << i << ' ';
}

您的 for_each 需要一个函数指针,但是 template argument deduction 不会考虑隐式转换(从 lambda 到函数指针),这会导致调用失败。

您可以显式执行转换:

for_each(five_elems, static_cast<void(*)(int&)>([](int& ref)/*->void*/{ref *= 2; std::cout << ref << ' '; }));

for_each(five_elems, +[](int& ref)/*->void*/{ref *= 2; std::cout << ref << ' '; });

或者干脆停止使用函数指针参数。您可以添加一个新的类型模板参数,然后直接添加 lambda。

template<typename T, size_t SIZE, typename F>
void for_each(std::array<T,SIZE>& arr, F func)
{
    for (auto i{0}; i != arr.size(); ++i)
        func(arr[i]);
}