[英]Handling constness of pointed values in map keys
我有以下代码:
#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();
}
我的问题是,当我在data
类型中注释和取消注释const
时,此代码在类型错误上失败。 有没有什么办法可以解决这个问题而不使用const_cast
并且不会丢失get_attached_value
的const
?
问题似乎是在pointee类型中 ,它在两个指针声明中都必须相同(map key type和get_attached_value
的参数)。
OP的代码使用const A*
,它是指向类A的const实例的指针(另一种拼写是A const *
)。 将此const保留在map声明和get_attached_value
'参数中几乎可以正常工作,但reset_all
不允许您为*p.first
分配新值,因为结果类型是A const&
(无法分配)。
删除两个consts也是有效的,但是OP希望在get_attached_value
保留一个const。
OP的要求的一个解决方案,保持尽可能多的consts,似乎是将指针类型更改为指向A的非const实例的const指针 。 这将使reset_all
保持工作,同时允许在map声明和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
和自定义比较器来替换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
的本机搜索功能的解决方案 - 当输入迭代器不是随机访问时, std::lower_bound
使用线性搜索 。
总而言之,C ++ 11或更低版本中最有效的解决方案可能使用const指针作为映射的键,并使用reset_all
函数中的const_cast
。
关于const表示法和指针的更多阅读可以在这里找到。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.