8

範囲 v3 のアルゴリズムはチェーン可能ではないようです。つまり、次のようになります。

const auto ints = std::vector<int>{1,2,1,3,1,4,1,5,1,6};
const auto num_ones = ints | ranges::count(1);

...機能的なスタイルで書かなければなりません:

const auto num_ones = ranges::count(ints, 1);

これは、新しい範囲/コンテナーを返すアルゴリズム/アクションのみがパイプ可能であるという設計上の選択ですか?

4

2 に答える 2

4

チェーン ビューの出力は、別のビュー (つまり、範囲) でなければなりません。そうすれば、より多くのビューを使用して結果をチェーンし続けることができます。

の結果はcount範囲ではないため、その操作をチェーンに含める意味はありません。可能だった仮説的なケースでは、その操作の結果を別のビューにチェーンすることはできません。

状況を別の角度から見ると、range-v3 ビューは遅延評価されます。範囲内の要素数のカウントは、結果を得るために範囲全体を評価する必要があるため、遅延操作ではありません。それは別の種類の操作です。

ranges::copyranges::sort、などの他の「自立型」アルゴリズムにも同じ推論を適用できますranges::min_element。これらは、対応するアルゴリズムのバリアント (または改良) と見なす必要がありstdますが、反復子のペアの代わりに範囲を引数として受け入れることもできます。 .

そうは言っても、独立したアルゴリズムの一部は、それが理にかなっているビューとしても利用できます (アルゴリズムのset_intersectionset_differenceおよびset_unionファミリなど)。

編集: この規則には例外があります。つまり、パイプされた範囲を a (または選択したコンテナー) に「シンク」する関数ranges::to_vectorおよび。ranges::to_std::vector

于 2018-04-24T09:18:38.360 に答える
2

一部のアルゴリズムは実際に連鎖可能であり、それらはビューおよび/またはアクションの名前空間にあります。

しかし、あなたのコードは、実際には別の質問があることを示唆しています。パイプチェーンを終了できる署名付きのアルゴリズムがないのはなぜですか? reducerそのようなアルゴリズムの名前空間を提案します。動作するコード例を次に示します。

#include <iostream>
#include <string>
#include <vector>
#include <range/v3/all.hpp>

using namespace std;
namespace view = ranges::view;
namespace action = ranges::action;

namespace reducer {
    template <typename T>
    class count {
        T t;
        public:
        count(T t) : t(t) {}
        template <typename Left>
        T operator()(Left left) {
            return ranges::count(left, t);
        }
    };

    template <typename Left, typename T>
    int operator|(Left left, count<T> right) {
        return right(left);
    }
}

int main (int argc, char * argv[])
{
    const auto ints = std::vector<int>{1,2,1,3,1,4,1,5,1,6};
    const auto num_ones = ints | reducer::count(1);
    cout << num_ones << endl;
    return 0;
}

Eric Niebler は、私たちと同じように、人々は多くのアイデアを思いつきでぶちまけますが、深刻な結果を目にすることはないと言いました。ですから、私たちが見えないという考えには何か悪いことがあるのではないでしょうか。彼があなたの質問を通り過ぎて、コメントで私たちを啓発してくれたら素晴らしいでしょう.

もちろん、彼は range-v3 に C++11 を使用しており、コンストラクターの型推定がなければ、このアイデアを実装するのは困難です。

于 2018-06-10T02:48:27.327 に答える