将迭代器放在容器内部
putting iterator on a container inside it
我想写一个模板,得到一个容器模板作为参数(如vector
, set
, unordered_set
)和一个类型T
,并返回一个双重链接的容器,即容器的每个项目应包含一个三重:
- a
T
- 一个
prev
迭代器,指向T
的其他三元组
next
迭代器指向T
的其他三元组内容如下:
template <template <class Tr> class Container, class T>
struct Triple {
T value;
typename Container< Triple<Container, T> >::iterator prev, next;
};
template <template <class Tr> class Container, class T>
using DoublyLinkedContainer = Container< Triple< Container, T> >;
#include <vector>
// default partial specialisation of the Allocator parameter
template <class T> using SimpleVector = std::vector<T>;
DoublyLinkedContainer<SimpleVector, int> v;
它似乎被编译器(gcc和clang)接受,但我不能理解如果我调用未定义的行为c++的递归类型定义是否可能,特别是我是否可以将vector
编辑:以下是@Richard Hodges询问的一些背景:
我想在容器中存储一组对象的分区(在数学意义上),以便与该分区相关联的等价类是有序的。因此,我的想法是将这些等价类作为链表,因为它符合我对快速删除和顺序迭代的需求。当我开始使用这些等价类时,这个集合将被固定,这样就不会出现迭代器失效的问题。当然,比较、相等和哈希只依赖于三元组的T
属性。
现在我不确定哪个容器更适合我的算法。因此,我正在尝试写这样一个模板来推迟选择。我可以在最后更改容器。
注意:如果我想要等效的向量,我也可以使用映射将两个迭代器关联到T
和boost::flat_set
,但这与这里提出的模板问题完全正交。
我认为这是你想要解决的问题的解决方案。
vec是Something对象的原始不可变向量(就像上面的T)。
weightedIndex是指向vec的交互器向量,在本例中,vec是通过Something.weight()升序排序的(但它可以是任何谓词)
#include <iostream>
#include <vector>
#include <algorithm>
struct Something
{
Something(int weight)
: _creationOrder { _createCount++ }
, _weight { weight }
{}
int weight() const { return _weight; }
std::ostream& write(std::ostream& os) const {
os << "Something { createOrder="
<< _creationOrder
<< ", weight=" << _weight << "}";
return os;
}
private:
int _creationOrder;
int _weight;
static int _createCount;
};
std::ostream& operator<<(std::ostream& os, const Something& st) {
return st.write(os);
}
int Something::_createCount { 0 };
using namespace std;
int main()
{
vector<Something> vec { 10, 23, 76, 12, 98, 11, 34 };
cout << "original list:";
for(const auto& item : vec) {
cout << "n" << item;
}
using iter = decltype(vec)::const_iterator;
vector<iter> weightIndex;
weightIndex.reserve(vec.size());
for(auto i = vec.begin() ; i != vec.end() ; ++i) {
weightIndex.push_back(i);
}
sort(weightIndex.begin(), weightIndex.end() , [](const iter& i1, const iter& i2) {
return i1->weight() < i2->weight();
});
// weightIndex is now a vector of pointers to the Something elements, but the pointers
// are ordered by weight of each Something
cout << "nSorted index:";
for(const auto p : weightIndex) {
cout << "n" << *p;
}
cout << endl;
// find the mid-weight
auto ii = next(weightIndex.begin(), 3);
// next one in list is
auto next_ii = next(ii, 1);
// find previous in weighted order
auto prev_ii = prev(ii, 1);
cout << "Selection:n";
cout << "Current = " << **ii << endl;
cout << "Next = " << **next_ii << endl;
cout << "Previous = " << **prev_ii << endl;
return 0;
}
输出:original list:
Something { createOrder=0, weight=10}
Something { createOrder=1, weight=23}
Something { createOrder=2, weight=76}
Something { createOrder=3, weight=12}
Something { createOrder=4, weight=98}
Something { createOrder=5, weight=11}
Something { createOrder=6, weight=34}
Sorted index:
Something { createOrder=0, weight=10}
Something { createOrder=5, weight=11}
Something { createOrder=3, weight=12}
Something { createOrder=1, weight=23}
Something { createOrder=6, weight=34}
Something { createOrder=2, weight=76}
Something { createOrder=4, weight=98}
Selection:
Current = Something { createOrder=1, weight=23}
Next = Something { createOrder=6, weight=34}
Previous = Something { createOrder=3, weight=12}
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 如何在c++迭代器类型中包装std::chrono
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 对于set上的循环-获取next元素迭代器
- 为什么output_editor Concept不需要output_e迭代器标记
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 使用迭代器时如何访问对象在向量中的位置?
- std::vector::迭代器是否可以合法地作为指针
- 跟随整数索引列表的自定义类迭代器
- 特征 使用 SIMD 迭代稀疏矩阵中的内部迭代器
- 我如何从循环内部使用迭代器的函数内部的getter中检索特定的成员
- 容器末端和指向内部项的迭代器之间的区别.C++
- C++ std::迭代器,内部不使用 std::vector 或 std::list
- 矢量迭代器不可解引用(矢量内部的矢量)
- 为什么 QVector 的迭代器使用前缀增加,而后缀在内部减少?
- 将迭代器放在容器内部
- 在将其用作参数时,在内部增加迭代器是否安全