1

これらのエラーが発生しています。なんで?

/usr/include/c++/4.7/algorithm:63:0 からインクルードされたファイルで、prog.cpp:2 から: /usr/include/c++/4.7/bits/stl_algo.h: '_OIter std::transform のインスタンス化で(_IIter、_IIter、_OIter、_UnaryOperation) [with _IIter = __gnu_cxx::__normal_iterator >; _OIter = std::back_insert_iterator >; _UnaryOperation = main()::]': prog.cpp:10:98: ここから必要 /usr/include/c++/4.7/bits/stl_algo.h:4951:2: エラー: '(main への呼び出しに一致しません()::) (int&)' prog.cpp:10:64: 注: 候補は: in file include from /usr/include/c++/4.7/algorithm:63:0, from prog.cpp:2: /usr /include/c++/4.7/bits/stl_algo.h:4951:2: 注: int (*)(int, int) /usr/include/c++/4.7/bits/stl_algo.h:4951:2: 注: 候補3 つの引数を想定し、2 つの引数を指定 prog.cpp:10:79: note: main():: prog.cpp:10:79: note:

#include <algorithm>
#include <vector>

int main()
{
    std::vector<int> v {1, 2, 3, 4, 5, 6};
    std::vector<int> r;

    std::transform(v.begin(), v.end(), std::back_inserter(r), [] (int a, int b) { return a + b; });
}

rこのコードは、数値の各ペアを合計してベクトルに入れることになっていますが、機能していません。何故ですか?

4

1 に答える 1

3

transform()単一の範囲で機能するオーバーロードを選択したため、最後の引数として単項ファンクターが提供されることが期待されます。

2 つの範囲 (おそらく同じ範囲の 2 つの「コピー」) で作業したい場合は、次のようにする必要があります。

std::transform(v.begin(), v.end(), v.begin(), 
//                                 ^^^^^^^^^
    std::back_inserter(r), [] (int a, int b) { return a + b; });

したがって、完全なコードは次のとおりです。

#include <algorithm>
#include <vector>

int main()
{
    std::vector<int> v {1, 2, 3, 4, 5, 6};
    std::vector<int> r;

    std::transform(v.begin(), v.end(), v.begin(),
        std::back_inserter(r), [] (int a, int b) { return a + b; });
}

そして、これはライブの例をコンパイルしています。

std::transform()ただし、 2 つの入力範囲で動作するのオーバーロードを練習したいだけでない限り、コメントからの Konrad Rudolph のアドバイスに従って、次のように書くことができます。

std::transform(v.begin(), v.end(), 
    std::back_inserter(r), [] (int a) { return a * 2; });

代わりに、変換のようなアプローチを使用しながら、連続する要素の各ペアの合計を実行し、結果をrベクターに格納する場合は、Boost.Range に頼って、次のように記述します。

#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>

// ...

namespace rng = boost::adaptors;

// This will fill r with values { 3, 7, 11 }
boost::transform(
    v | rng::strided(2),
    std::make_pair(v.begin() + 1, v.end()) | rng::strided(2),
    std::back_inserter(r),
    [] (int a, int b) { return a + b; });

これが実際のです。

また、コメントで NeelBasu が指摘したように、 を使用して 2 番目の範囲を定義する代わりに、範囲アダプターstd::make_pair()に基づいてより表現力豊かな (そしてコンパクトな) バージョンを作成できます。sliced

boost::transform(
    v | rng::strided(2),
    v | rng::sliced(1, v.size()) | rng::strided(2),
    std::back_inserter(r),
    [] (int a, int b) { return a + b; });
于 2013-06-08T15:30:55.697 に答える