我有以下代码:
#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
的情况下解决这个问题?
答案 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。