2

C ++ 11

最後の2行の1行バージョンがあるはずです。

        typedef std::pair<T1, T2> impl_node;
        std::vector<impl_node> impl;
        /* do stuff with impl */
        std::vector<T1> retval(impl.size());
        std::transform(impl.cbegin(), impl.cend(), retval.begin(),
                         [](const impl_node& in) { return *in.first; });

ある種のカスタムイテレータアダプタを書いてみましたが、タイプが複雑になっています。「正しい」解決策は何ですか?(そして、それはおそらく他のあらゆる種類のアダプターに一般化されます。)

4

4 に答える 4

3

これはまだ 2 行ですが、タイピングは (両方の意味で) 少なくなります。

std::vector<T1> retval(impl.size());
for (const auto& p : impl) retval.push_back(p.first); 

実際、今見てみると、次の 3 行が望ましいと思います。

std::vector<T1> retval;
retval.reserve(impl.size());
for (const auto& p : impl) retval.push_back(p.first); 

(適切であるという証拠がないため、移動を削除するように編集されました)

于 2012-12-13T21:47:29.253 に答える
0

さて、これから始めることができます:

template<typename Output, typename Input, typename Transformation>
auto transform( Input const& input, Transformation t )->Output {
  Output retval;
  retval.reserve(input.size());
  using std::cbegin; using std::cend;
  std::transform(cbegin(input), cend(input), std::back_inserter(retval));
  return retval;
}

次に、次のような作業を行います。

namespace aux{
  using std::cbegin;
  template<typename T>
  auto adl_cbegin( T&& t )->decltype(cbegin(std::forward(t)));
}
template<typename Input, typename Transformation>
auto transform_vec( Input const& input, Transformation t )->
    std::vector<typename std::remove_ref<decltype(t(*adl_cbegin(input)))>::type>
{
  typedef std::vector<typename std::remove_ref<decltype(t(*adl_cbegin(input)))>::type> Output;
  Output retval;
//      retval.reserve(input.size()); -- need a way to do this if Input has an easy way to get size.  Too lazy to bother right now.
  using std::cbegin; using std::cend;
  std::transform(cbegin(input), cend(input), std::back_inserter(retval));
  return retval;
}

注:これは反復可能なもの(ベクトル、配列、イテレーターのペア)を取り、そこから入力範囲でstd::pairのを生成するようにアップグレードするboost::transform_iteratorため、結果の変換を任意のコンテナーに挿入できます。実際にイテレータを逆参照すると、変換が機能します。

または、ご存知のとおり、std::back_inserter(input)直接使用してください。:)そのアプローチの欠点は、リザーブを実行しないため、パフォーマンスに影響が出るということです。

于 2012-12-13T21:50:22.880 に答える
0

少なくとも (テンプレート化された) ヘルパー関数を最初に記述せずに、C++11 の標準 STL のみを使用して 1 行でこれを行う方法を知りません。

2 つの反復子が 1 つのオブジェクトになり、C++ が .NET の LINQ 拡張メソッドと同様の動作をサポートし始めるという概念を探しているかもしれません: http://www.boost.org/doc/libs/1_52_0/libs/range/ドキュメント/html/index.html

于 2012-12-13T21:28:27.580 に答える
0

挿入反復子を使用すると、探しているものの少なくとも半分を取得できます。

vectorサイズを指定せずに割り当て、

std::vector<T1> retval;

...そして、back_inserter(から#include <iterator>)を使用して入力します:

std::transform(impl.cbegin(), impl.cend(), back_inserter(retval),[](const impl_node& in) { return *in.first; });
于 2012-12-13T21:46:56.227 に答える