Как создать итератор для элемента-члена из итератора контейнера std? - PullRequest
0 голосов
/ 12 января 2019

Мне нужно создать итератор только для элемента-члена, который будет перебирать контейнер.

Например:

class A { int x; char y; };

std::vector<A> mycoll = {{10,'a'}, {20,'b'}, {30,'c'} };

Здесь mycoll.begin() даст мне итератор типа A

Но мне требуется написать итератор для итерации по конкретному члену (скажем, x A.x), и пусть int_ite будет итератором для этого целого числа.

Тогда мне нужно

*(int_ite.begin() ) чтобы вернуть 10

*(++int_ite.begin() ) чтобы вернуть 20

и т. Д.

также .end() даст конец итерации.

Есть ли какой-нибудь элегантный способ создать такой итератор? Мне нужно, чтобы передать это std::lower_bound()

Ответы [ 2 ]

0 голосов
/ 12 января 2019

От cppreference (перегрузка (2)):

template< class ForwardIt, class T, class Compare >
ForwardIt lower_bound( ForwardIt first, ForwardIt last, const T& value, Compare comp );

Чтобы найти нижнюю границу относительно элемента x, вы можете передать компаратор, который сравнивает этот элемент как последний параметр.

Обычно вы передаете функтор в алгоритмы, которые определяют, как элементы контейнера обрабатываются или оцениваются, вместо того, чтобы писать сложные итераторы. Поддержка написания собственных причудливых итераторов в стандартной библиотеке довольно скудна, а алгоритмы довольно мощные.

0 голосов
/ 12 января 2019

С range-v3 , вы можете создать представление:

std::vector<A> mycoll = {{10,'a'}, {20,'b'}, {30,'c'} };

for (auto e : mycoll | ranges::view::transform(&A::x)) {
    std::cout << e << " "; // 10 20 30
}

А для lower_bound у range-v3 есть проекция:

auto it = ranges::v3::lower_bound(mycoll, value, std::less<>{}, &A::x);
// return iterator of mycoll directly :-)

Остальное с std, вы можете использовать пользовательский компаратор с std::lower_bound

auto it = std::lower_bound(mycoll.begin(), mycoll.end(),
                           value,
                           [](const A& a, int x){ return a.x < x; });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...