从 lambda 内部返回 C++11 中的 lambda 类型(平面映射函数)

Return type of lambda in C++11 from inside the lambda (flat map function)

本文关键字:lambda 平面 类型 映射函数 中的 内部 返回 C++11      更新时间:2023-10-16

我已经在 scala 的平面映射上实现了一个函数,我想知道我是否可以访问 lambda 内部 lambda 的返回类型,以避免在使用时重复它

/**
 * Inspired on scala's flat map, provide a @param func which output will be flattened in the output
 * sequence, which is the return type of @param func
 */
template <typename IN, typename F>
auto flat_mapf(const IN& input, F func)
    -> decltype(func(std::declval<typename IN::value_type>()))
{
    decltype(func(std::declval<typename IN::value_type>())) output;
    auto outit = std::back_inserter(output);
    for (auto i = input.begin(); i != input.end(); ++i)
    {
        decltype(func(std::declval<typename IN::value_type>())) interm = func(*i);
        std::move(interm.begin(), interm.end(), outit);
    }
    return output;
}

// usage example, I would like to avoid repeating vector<size_t> type two times:
auto vo = flat_mapf(vi, [](const size_t& x) -> vector<size_t> {
    vector<size_t> res;
    for (size_t i = 0; i < x; ++i)
        res.push_back(x);
    return res;
});

您不能从用法示例中省略-> vector<size_t>,以便编译器推断 lambda 的返回类型吗?这样你只说一次类型。

由于您要提供的功能适用于范围(这是非常合理的事情),我可以向您指出 Boost.Range。用户将能够将您的flat_mapf与例如 boost::irange像这样:

auto vo = flat_mapf(vi, [](size_t x) {
    return boost::irange(size_t { 0 }, x);
 });

boost::irange仅适用于整型,boost::counting_range更通用。

返回实际向量可能不是正确的方法。 这要求在累积在一起之前生成和缓存每个元素的所有输出。

某种生成器模式,例如返回提升可选(空表示已完成生成)的子映射函子等意味着您不需要中间容器。 将这样的生成器转换为 std 向量很容易,当每个子映射都是生成器 lambda 时编写平面映射也很容易。

我提出这个是因为这也意味着双类型规范消失了。 在三位一体运算符不起作用的情况下,您只有一个位置返回,然后另一个位置返回空。

简而言之,也许你输入了大量的std向量,因为你正在制作很多std向量。