【发布时间】:2019-01-31 22:49:00
【问题描述】:
我正在尝试概括一个函数,该函数用于将两个迭代器用于特定数据结构的向量,并使用std::iter_swap 以某种方式重新排列元素(就像std::sort 一样)。
由于这个函数实际上只需要数据的一个子集,而且我以后需要在其他上下文中使用它,所以我考虑去除对数据结构的依赖,并在调用时使用boost::transform_iterator处理转换。
不幸的是,boost::transform_iterator 似乎对这种变化并不满意。我可以想象为什么:std::iter_swap 通常实现为std::swap(*lhs, *rhs),而取消引用transform_iterator 不会产生以正确方式交换的原始元素。
我想知道是否有办法处理这种情况。如果需要,我愿意使用boost::range 或实验性的std::ranges ts。
这个问题可能类似于this one,但即便如此,解决方案最终也会修改算法所需的数据子集,而不是外部结构。
这是一个 MWE:
#include <boost/iterator/transform_iterator.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
struct A {
int x;
int y;
};
template <typename It>
void my_invert(It begin, It end) {
while (begin < end) {
std::iter_swap(begin++, --end);
}
}
template <typename It>
void my_print(It begin, It end) {
for (; begin != end; ++begin)
std::cout << (*begin) << ' ';
std::cout << '\n';
}
int main() {
std::vector<int> x{7,6,5,4,3,2};
my_invert(std::begin(x), std::end(x));
my_print(std::begin(x), std::end(x));
auto unwrap = +[](const A & a) { return a.x; };
std::vector<A> y{{9,8}, {7,6}, {5,4}, {3,2}};
auto begin = boost::make_transform_iterator(std::begin(y), unwrap);
auto end = boost::make_transform_iterator(std::end(y), unwrap);
//my_invert(begin, end); // Does not work.
my_print(begin, end);
return 0;
}
【问题讨论】: