10

std::vectorMyClass のオブジェクトを保持するa が与えられます。を使用して MyClass の 1 つのメンバーのデータのみを保持する別のベクトルを作成するにはどうすればよいstd::copyですか? カスタムを実装する必要があると思いback_inserterますが、これまでのところ、これを行う方法がわかりませんでした。

struct MyClass {
   int a;
}

std::vector<MyClass> vec1;

// I could copy that to another vector of type MyClass using std::copy.
std::copy(vec1.begin(), vec1.end(); std::back_inserter(someOtherVec)

// However I want just the data of the member a, how can I do that using std::copy?
std::vector<int> vec2;
4

2 に答える 2

18

そのために使用std::transformします。

std::transform(vec1.begin(), vec1.end(), std::back_inserter(vec2),
               [](const MyClass& cls) { return cls.a; });

(C++11 を使用できない場合は、自分で関数オブジェクトを作成できます。

struct AGetter { int operator()(const MyClass& cls) const { return cls.a; } };

std::transform(vec1.begin(), vec1.end(), std::back_inserter(vec2), AGetter());

または、std::tr1::bindTR1 を使用できる場合に使用します。

std::transform(vec1.begin(), vec1.end(), std::back_inserter(vec2),
               std::tr1::bind(&MyClass::a, std::tr1::placeholders::_1));

ところで、@Nawaz が以下でコメントしたよう.reserve()に、コピー中の不要な再割り当てを防ぐために a を実行します。

vec2.reserve(vec1.size());
std::transform(...);
于 2012-07-27T11:36:39.280 に答える
4

std::transformnotstd::copyを使用std::bindし、メンバー変数へのポインターにバインドします。

#include <algorithm>
#include <iterator>
#include <vector>
#include <iostream>
#include <functional>

struct foo {
  int a;
};

int main() {
  const std::vector<foo> f = {{0},{1},{2}};
  std::vector<int> out;

  out.reserve(f.size());
  std::transform(f.begin(), f.end(), std::back_inserter(out), 
                 std::bind(&foo::a, std::placeholders::_1));

  // Print to prove it worked:
  std::copy(out.begin(), out.end(), std::ostream_iterator<int>(std::cout, "\n"));
}

私の例は C++11 ですが、便利なベクトルの初期化をスキップしてboost::bind代わりに使用すると、C++11 がなくても同じように機能します。

于 2012-07-27T11:39:31.597 に答える