3

我已经在 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;
});
4

3 回答 3

0

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

于 2012-11-22T12:55:45.420 回答
0

由于您要提供的功能适用于范围(这是非常合理的事情),我可以向您指出 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更通用。)

于 2012-11-22T13:21:08.410 回答
0

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

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

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

简而言之,也许您正在输入大量标准向量,因为您正在制作大量标准向量。

于 2012-11-22T13:40:01.323 回答