高次リスト関数のC ++ 11サポート


13

などなど、ほとんどの関数型プログラミング言語(例えばCommon Lispの、スキーム/ラケット、Clojureの、ハスケル、スカラ座、OCamlで、SML)リスト上のいくつかの一般的な高階関数をサポートするには、mapfiltertakeWhiledropWhilefoldlfoldr(例えば参照、Common Lispの、スキーム/ラケットをClojureの並列リファレンスシートHaskellScalaOCaml、およびSMLドキュメント。

C ++ 11には、リストに同等の標準メソッドまたは関数がありますか?たとえば、次のHaskellスニペットを考えます。

let xs = [1, 2, 3, 4, 5]
let ys = map (\x -> x * x) xs

最新の標準C ++で2番目の式をどのように表現できますか?

std::list<int> xs = ... // Initialize the list in some way.
std::list<int> ys = ??? // How to translate the Haskell expression?

上記の他の高階関数はどうですか?
C ++で直接表現できますか?


はい。ただし、二重リンクリストの特定の実装よりも一般的な概念で動作します。この領域でのPythonの操作も同様です。私は、特定のデータ構造に結び付けられることを非常に好みます。Data.SequenceHaskellでこれらの操作を実行しようとしたことがありますか?それは比較的いです。

「それは比較的いです。」:何と比較して?
ジョルジオ

の同じ操作と比較して[a]。プレリュード機能を非表示にするか、プレリュードをハックするか、別のわかりにくい名前を選択する必要があります。

おそらくあなたは正しいかもしれませんが、この質問のトピックは、HaskellのData.Sequenceに類似した関数を実装する方法ではなく、C ++で共通リストの高階関数を表現する方法です。
ジョルジオ

1
@delnan Haskellのアプローチははるかに一般的であると主張します。FunctorFoldableTraversable私は考えることができるよう抽象的なAの方法としてでこれを実現します。Data.Sequenceこれらすべてのインスタンスであるため、を実行できますfmap (\x -> x * x) xsmapされfmap、初心者に特化。
アレック

回答:


16

さらに、C ++にはそのような機能があります。アルゴリズム(またはC ++ 11の追加)ヘッダーを見てください。

std::transform
std::for_each
std::remove_copy_if

任意のコンテナで簡単に使用できます。

たとえば、コードは次のように表現できます(簡単なコーディングのためにC ++ 11ラムダを使用):

std::vector<int> x = {1, 2, 3, 4, 5};
std::vector<int> y;
std::transform(x.begin(), x.end(), std::back_inserter(y), [](int elem){ return elem * elem; });

直感的ではありませんが、std::transform新しいコンテナを返す関数に呼び出しを簡単にラップできます(moveパフォーマンスを向上させるためのセマンティクスを使用)。


ありがとう。数日前に書いたコードをいくつか簡略化したいと思います。これにより、コードを大幅に短縮できます。ただ一つの小さな質問:なぜx.begin()とx.end()を渡す必要があるのですか?ベクトルxを渡すだけでは十分ではないでしょうか?
ジョルジオ

std::transform2つのイテレーターを使用するため、コンテナーのスライスを取ることができます(イテレーターの算術演算があることを思い出してください)。
m0nhawk

したがって、2つの操作が1つになります。スライスの取得と変換の適用です。
ジョルジオ

以前は、2つのイテレータがあり、それらの間の要素に変換を適用していました。イテレーターは関数型プログラミングでは一般的ではありません。
m0nhawk

2
私はそのようなライブラリに出会ったことがなく、C ++では反復子ベースのアルゴリズムが非常に便利です。あなたの場合、次のstd::transformようなラッパーを作成できますY<U> map(T<U>, std::function<Y(U)>)
m0nhawk
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.