3

scala のフラット マップにインスパイアされた関数を実装しましたが、ラムダ内のラムダの戻り値の型にアクセスして、使用時に繰り返しを回避できるかどうか疑問に思います

/**
 * 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

あなたが提供したい機能は範囲で動作するため (これは非常に合理的なことです)、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

使用例から theを省略して-> vector<size_t>、コンパイラがラムダの戻り値の型を推測することはできませんか? そうすれば、タイプを一度だけ言うことができます。

于 2012-11-22T12:55:45.420 に答える
0

実際のベクトルを返すことは、ここでは適切なアプローチではない可能性があります。そのためには、各要素からのすべての出力を生成してキャッシュしてから、それらをまとめて蓄積する必要があります。

ブーストオプションを返すサブマップファンクター(空の意味は生成が終了したことを意味します)など、ある種のジェネレーターパターンは、中間コンテナーを必要としないことを意味します。このようなジェネレーターを std ベクトルに変換するのは簡単で、各サブマップがジェネレーター ラムダである場合にフラット マップを記述するのも簡単です。

ダブルタイプの仕様がなくなるという意味でもあるので取り上げます。三項演算子が機能しない状況では、1 つの場所だけが返され、他の場所は空になります。

要するに、多くの std ベクトルを作成しているため、多くの std ベクトルを入力している可能性があります。

于 2012-11-22T13:40:01.323 に答える