- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试概括一个函数,该函数用于将两个迭代器带入特定数据结构的 vector ,并使用 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;
}
最佳答案
您可以访问 base()
transform_iterator
的属性(从 iterator_adaptor
公开继承)来实现您的自定义 transform_iter_swap
,用于交换包装迭代器的基础数据。
例如:
template<class IteratorAdaptor>
void transform_iter_swap(IteratorAdaptor a, IteratorAdaptor b)
{
std::swap(*a.base(), *b.base());
}
template <typename It>
void my_invert(It begin, It end) {
while (begin < end) {
transform_iter_swap(begin++, --end);
}
}
之后您的示例(省略 std::vector
部分)按预期运行:
my_invert(begin, end); // OK
my_print(begin, end); // 3 5 7 9
如果你想要一个通用的函数模板来覆盖 boost(适配器)迭代器和典型的迭代器,你可以例如根据迭代器 public typedef
iterator_category
是否派生自 boost::iterators::no_traversal_tag 使用
与否:if constexpr
(C++17)
// expand includes with
#include <boost/iterator/iterator_categories.hpp>
template <class It>
void iter_swap(It a, It b) {
if constexpr(std::is_base_of<
boost::iterators::no_traversal_tag,
typename It::iterator_category>::value) {
std::swap(*a.base(), *b.base());
}
else {
std::swap(*a, *b);
}
}
template <typename It>
void my_invert(It begin, It end) {
while (begin < end) {
iter_swap(begin++, --end);
}
}
关于c++ - boost::transform_iterator 和 std::iter_swap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52021673/
如果我有一个容器 std::vector items ,我可以创建一个 IndirectIterator包装 std::vector::iterator并允许遍历 T的而不是 T*的。 我可以专攻it
我只是想知道,为什么有人会写这个: std::iter_swap(i, k); 而不是这个? std::swap(*i, *k); // saved a few keystrokes! 然后我研究
MSDN says : swap should be used in preference to iter_swap, which was included in the C++ Standard f
实现基本的冒泡排序以按名称对 Student 结构的 vector 进行排序。 #include #include void sortStudents(std::vector& students)
我有一个“简单”的问题:我正在尝试交换 map 中的对以更改顺序。此代码无法编译。 #include #include #include #include int main() { std
我将一个包含 20 个项目的 vector 传递给下面的函数。我的目标是更改 vector 中项目的顺序。如果列表包含项目 1 2 3 4,我希望最终结果为 4 3 2 1。基本上将第一项与最后一项切
我正在尝试概括一个函数,该函数用于将两个迭代器带入特定数据结构的 vector ,并使用 std::iter_swap 以特定方式重新排列元素(就像 std::sort 那样)。 由于这个函数实际上只
从 David Abrahams 和 Aleksey Gurtovoy 的书“C++ 模板元编程”中,我了解到 iter_swap (见下文)会比 std::swap 慢得多有时。虽然这本书有一些解释
查看std::iter_swap reference我的结论是: struct A {}; std::experimental::optional x{A{}}, y{A{}}; std::iter_
为什么/什么时候我们应该更喜欢 using std::swap; swap(a, b); over std::iter_swap(&a, &b)? 最佳答案 因为它们完全不同,所以你的问题是错误的二分
我很难理解为什么在下面的代码中直接调用 std::swap() 会导致编译错误,而使用 std::iter_swap 编译却没有任何错误. 来自 iter_swap() versus swap() -
我是一名优秀的程序员,十分优秀!