Как копировать с доступом пользователя с помощью Boost

У меня есть контейнер как с

struct A { int f(); }

Контейнер предлагает итераторы, и мы можем для этого примера предположить, что это std :: vector. Так:

std::vector<A> As;

Теперь я хочу скопировать значения, предоставленные A :: f, во второй контейнер

std::vector<int> fs;

Хотя я мог просто выполнять итерации, в качестве упражнения я пытался решить эту проблему с помощью итератора boost bind / boost. Что я пробовал до сих пор это:

std::copy(
boost::make_transform_iterator
(As.begin(), boost::bind(&A::f, _1)),
boost::make_transform_iterator
(As.begin(), boost::bind(&A::f, _1)),
std::back_inserter( fs )
);

Кто-нибудь знает, как это можно сделать?

2

Решение

Если я изменю второй итератор make_transform, чтобы он указывал на end () вместо begin (), все работает.

#include <boost/iterator/transform_iterator.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <vector>

struct A {
int f() {
static int x = 0;
return x++;
};
};

int main() {
std::vector<A> As;
As.push_back(A());
As.push_back(A());
As.push_back(A());

std::vector<int> fs;

std::copy(
boost::make_transform_iterator(As.begin(), boost::bind(&A::f, _1)),
boost::make_transform_iterator(As.end(),   boost::bind(&A::f, _1)),
std::back_inserter(fs)
);

for (int const & x : fs)
std::cout << x << std::endl;
}

Выход

0
1
2

Альтернативные решения

Вы также можете решить это с помощью функтора:

struct Functor {
int operator()(A & value) const {
return value.f();
}
};

std::transform(As.begin(), As.end(), std::back_inserter(fs), Functor());

или с лямбдой:

std::transform(As.begin(), As.end(), std::back_inserter(fs), [](A & a) { return a.f(); });
3

Другие решения

Вы хотите функциональный объект, который вы передаете make_transform_iterator взять A и вернуть результат вызова f на что A, Хотя вы можете сделать это, как вы сделали с bind, вы можете сделать это более явно с std::mem_fn:

std::copy(
boost::make_transform_iterator
(As.begin(), std::mem_fn(&A::f)),
boost::make_transform_iterator
(As.end(), std::mem_fn(&A::f)),
std::back_inserter( fs )
);

Обратите внимание, что второй итератор преобразования должен адаптироваться As.end(),

1

По вопросам рекламы [email protected]