我正在创建一个将其底层实现作为有序向量的映射。它可能最终与Boost flat map非常相似。我们的想法是通过将映射中的所有对存储在连续的内存中来妥协较慢的插入和删除以实现更快的访问。它也被设计成替代地图,具有完全相同的界面。迭代器失效会出现一些与地图合同不同的问题,但我准备处理这些问题。我所面临的问题的简单解释是这段(非编译)代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
const int a = 10;
int b = 20;
pair<const int, int> constPair1(a,b);
b=30;
const int c = 40;
pair<const int, int> constPair2(c,b);
vector<pair<const int, int>> vec{constPair1,constPair2};
sort(vec.begin(),vec.end());
return 0;
}
我遇到的问题是如何处理const
。上面的代码不会编译,因为不允许sort在const
对中移动。 Boost平面地图似乎只是忽略了问题而放弃了const
限定符,但是,我希望替换掉,所以这不是一个选项。如何保持相同的接口但仍然允许底层排序的接口?如果可能的话,我想避免const_cast
。
答案 0 :(得分:-1)
问题是const
语义非常粗糙,并且使用例如const const对象的非const数组或非const对象的const数组只是不适合这个模式。 / p>
一种可能的解决方法是将数据保存在非const数组中,并使用指针转换技巧来提供接口。换句话说,当您通过pair<const int, int> p
时,只需使用pair<int, int>& ncp(*((pair<int, int>*)&p));
。将对象返回给用户时,您也可以这样做。
正式IIRC这不能保证工作,但在实现中我知道是可以的,优化器应该足够聪明,不能为这种观点变化生成代码。一个问题可能是严格的别名假设优化(btw会给很多低级代码带来问题),在这种情况下可能正在使用联合可以解决问题(当然仍然对标准不正确)。
在我看来,在我看来,这样一个&#34;地图&#34;会有更多的问题,只是迭代器失效。例如,我使用的模式(我打赌其他人也使用)依赖于迭代器可能无效的事实,但值本身永远不会移动...例如在执行之后
MyClass& foo() {
...
return my_map[key];
}
即使在地图中添加或删除了其他元素,我也可以确定返回的引用仍然有效。请注意,不使用迭代器。
将元素保存在向量中并在元素插入时移动它们(或者在插入后首次访问)也会破坏这种用法。