假设我有一个表示键的random access iterator(另请参见相关的type traits)和一个表示值(请注意,不一定是单个值)的随机访问迭代器。是否可以将它们组合到新的随机访问迭代器中,以与std::sort
同时进行排序(按键,但同时置换键和值)? std::sort
仅接受一个迭代器。以及如何仅使用核心C ++做到这一点?
我试图在一个引用元组上指定一个新的迭代器,但是问题是如何使交换与rvalues(带有一些代理?)一起工作?
此外,这两个序列的大小很大,因此我无法复制它们的值来创建对,甚至无法分配引用的数据结构。实际上,您可以尝试查看无法对引用对的向量进行排序(请考虑一下operator=
在此情况下的行为)。因此,此代码将失败(除非std::sort
决定仅使用swap
):
int arr1[] = {3, 2, -100, 5, 6, -200, 4, 0, -1, 2, 11, 12, -3, -4, -15};
int arr2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
std::vector<std::tuple<int&, int&>> pairs;
for (int i = 0; i < len; ++i) {
pairs.push_back(std::tie(arr1[i], arr2[i]));
}
std::sort(pairs.begin(), pairs.end(), [](auto lhs, auto rhs) {return std::get<0>(lhs) < std::get<1>(rhs);});
arrays print outs:
-15 -15 -15 -15 -15 -15 -15 -15 -15 -15 -15 -15 -15 -15 -15
14 14 14 14 14 14 14 14 14 14 14 14 14 14 14
到目前为止,我发现了这一点: https://web.archive.org/web/20120422174751/http://www.stanford.edu/~dgleich/notebook/2006/03/sorting_two_arrays_simultaneou.html。 但是,此解决方案使用升压,并且不兼容交换。
更新:我能够通过在引用元组上创建包装器来解决交换问题。但是现在我有一个搬家问题。 std::sort
提取并分配值。但是我该如何做参考呢? (请参见上面的无效代码)。
答案 0 :(得分:1)
受this thread的启发,我似乎可以通过在tuple
上编写自定义包装程序来解决此问题,如下所示:
template <typename ...Ts>
struct references_holder {
using tuple_references = std::tuple<Ts&...>;
using tuple_values = std::tuple<Ts...>;
references_holder(tuple_references data)
: data{data}
{}
operator tuple_references() {
return data;
}
tuple_references& as_tuple() {
return data;
}
operator tuple_values() {
return data;
}
references_holder& operator=(tuple_values val) {
data = val;
return *this;
}
tuple_references data;
};
template <typename ...Ts>
void swap(references_holder<Ts...> th1, references_holder<Ts...> th2) {
return std::swap(th1.data, th2.data);
}
template<int N, typename ...Ts>
auto get(references_holder<Ts...>& th) -> decltype(std::get<N>(th.data)){
return std::get<N>(th.data);
}
在我的复合迭代器中:
template <typename KeyIterator, typename ValueIterator>
class CompositeIterator {
public:
using key_iterator_value_type =
typename std::iterator_traits<KeyIterator>::value_type;
using value_iterator_value_type =
typename std::iterator_traits<ValueIterator>::value_type;
using value_type = std::tuple<
key_iterator_value_type,
value_iterator_value_type>;
using reference = references_holder<
key_iterator_value_type,
value_iterator_value_type>;
...
它绝对假定模板相关类型具有reference = value_type&
。其余的基于value_type
和reference
实现。