处理映射键中指向值的常量

时间:2015-03-15 21:33:34

标签: c++ types casting stl const

我有以下代码:

#include <map>
using namespace std;
struct A {};

map</*const*/ A *, int> data;

int get_attached_value(const A *p) {
    return data.at(p);
}
void reset_all() {
    for (const auto &p : data) *p.first = A();
}

我的问题是,当我在const类型中评论和取消注释data时,此代码都会因类型错误而失败。有没有办法在不使用const_cast且不丢失const中的get_attached_value的情况下解决这个问题?

1 个答案:

答案 0 :(得分:2)

问题似乎在指针类型中,在两个指针声明(映射键类型和get_attached_value的参数)中必须相同。

OP的代码使用const A*,它是指向A类的 const实例的指针(另一种拼写是A const *)。将此const保留在地图声明和get_attached_value&#39;参数几乎可行,但reset_all不允许您为*p.first分配新值,因为结果类型为A const&(无法分配)。

删除两个consts也是有效的,但OP希望在get_attached_value中保留一个const。

OP的要求的一个解决方案,保持尽可能多的consts,似乎是将指针类型更改为指向A 的非const实例的 const指针。这将使reset_all工作,同时允许在地图声明和get_attached_value参数中使用const指针:

#include <map>
using namespace std;
struct A {};

map<A * const, int> data;

int get_attached_value(A * const p) {
    return data.at(p);
}
void reset_all() {
    for (const auto &p : data)
        *p.first = A();
}

另一种可能的解决方案,即将map键作为非const而get_attached_value的参数const,可以使用std::lower_bound和自定义比较器来替换{{1调用:

data.at()

但是,此解决方案的效率远低于使用#include <map> #include <algorithm> using namespace std; struct A {}; map<A*, int> data; int get_attached_value(A const * const p) { auto it = std::lower_bound(data.begin(), data.end(), p, [] (const std::pair<A* const, int>& a, A const* const b) { return a.first < b; } ); return it->second; } void reset_all() { for (const auto &p : data) *p.first = A(); } 原生搜索功能的解决方案 - map uses linear search when input iterators are not random access

总而言之,C ++ 11或更低版本中最有效的解决方案可能会使用const指针作为地图的密钥,并使用std::lower_bound函数中的const_cast

可以找到关于const表示法和指针的更多内容here