У меня возникла странная проблема. У меня есть vector<pair<bool, int>>
, из которого мне нужно читать (и, возможно, писать) только векторные элементы, для которых логическое значение пары истинно. Для этого я использую фильтр расширенного диапазона и обратные адаптеры.C++: итератор с расширенным диапазоном, указывающий на неправильный элемент
Тем не менее, я заметил, что порядок адаптеров, т. Е. Использует ли меня обратный | фильтруют или фильтруют | обратный результат дает разные результаты. Фактически, когда я использую фильтр | обратный, тогда, когда я использую итератор для преобразованного диапазона, чтобы изменить логическое значение пары, тогда итератор после изменения указывает на другой векторный элемент. Этого не происходит, когда я использую обратное | фильтруют. Ниже приведен код, демонстрирующий проблему. Любые идеи относительно того, почему это происходит, очень ценятся!
#include <boost/range/adaptors.hpp>
#include <vector>
#include <utility>
#include <iostream>
using namespace boost::adaptors;
using container_type = std::vector<std::pair<bool,int>>;
struct to_include {
bool operator()(const std::pair<bool,int>& x) {
return x.first;
}
};
int main() {
container_type container;
/* element0: 1, 1 */
/* element1: 1, 2 */
/* element2: 1, 3 */
for(size_t i=0; i!=3; ++i) container.push_back(std::make_pair(true, i+1));
container_type container_cpy = container;
/* filter and then reverse */
auto fr = container | filtered(to_include()) | reversed;
auto fr_it1 = fr.begin();
auto fr_it2 = std::next(fr_it1);
fr_it2->first = false;
std::cout << "FILTER AND THEN REVERSE\n";
std::cout << fr_it2->first << " " << fr_it2->second << '\n'; /* prints (1,1) instead of (0,2) */
/* reverse and then filter */
auto rf = container_cpy | reversed | filtered(to_include());
auto rf_it1 = rf.begin();
auto rf_it2 = std::next(rf_it1);
rf_it2->first = false;
std::cout << "\nREVERSE AND THEN FILTER\n";
std::cout << rf_it2->first << " " << rf_it2->second << '\n'; /* prints (0,2) */
return 0;
}
Я, по общему признанию, не имел опыта с адаптерами дальнего радиуса действия, но для меня было бы разумно, если 'fr' был своего рода * обратным * диапазоном, так что' fr_it1' должен быть 'rbegin' вместо' begin'. – us2012
@ us2012: спасибо за помощь. 'fr' - это обратный диапазон (на самом деле это измененный диапазон фильтров), что означает, что его итератор' begin' указывает на последний элемент исходного контейнера (т.е. до реверсии). – linuxfever