Gab*_*iel 20 c++ stdmap c++11 c++14
我有以下问题:
std::map<A*,double> map;
void getColor(A const * obj){
double d = map[obj]; // does not compile wihtout const_cast<A*>(obj)
// do something
}
Run Code Online (Sandbox Code Playgroud)
我有一个地图std::map(某处)存储指向对象的指针A.我有一个不操纵对象的函数getColor, 因此将指针 作为输入.Aconst A
如果getColor不使用const_cast ,函数将无法编译.
const cast是一个设计问题,但如果我不想在map const中创建键,我不知道如何规避它.
任何帮助赞赏.
Rei*_*ica 19
这里有两种可能的情况:
该函数知道/期望obj已经存在于地图中,并且[]为方便起见而使用.
你正在[]充分利用它的潜力,即obj如果还没有它,你希望它添加到地图中.
在情境2中,getColor签名中存在错误.由于它可能会传递obj到它将被存储的地方,因此仅A*接受一个地方是错误的const A*.请注意,即使函数不修改对象本身但将其传递到可以修改的某个地方,它也会间接地对其进行修改,因此应将其视为非const.
在情况1中,它取决于您的C++版本.C++ 14引入一个的模板过载find和相关的成员函数的std::map这需要任何可比用Key而不是仅Key.因此,您可以像这样修改函数:
void getColor( A const * obj){
doubel d = map.find(obj)->second;
// do something
}
Run Code Online (Sandbox Code Playgroud)
请注意,要使其工作,您还需要更改地图的类型以使用透明比较器:( std::map<A*,double, std::less<>> map;首先由@Leon的回答指出).
如果你坚持使用C++ 11或更早版本,那么你运气不好,你将不得不忍受const_cast.请注意,通过合适的注释,a const_cast在这种情况下是完全安全且可接受的(更不用说在不改变类型的情况下继续进行的唯一方法map).同样,你应该使用find或者at代替[],因为你不想插入地图.
如果你能负担得起切换到C++ 14那么你可以配置你的地图使用透明比较器(这将工作,因为const指针可以与非const指针进行比较):
std::map<A*,double, std::less<>> map;
// ^^^^^^^^^^^
// enable transparent comparator on this map
void getColor( A const * obj){
auto it = map.find(obj);
assert(it != map.end());
double d = it->second;
// do something
}
Run Code Online (Sandbox Code Playgroud)
请注意,您必须使用std::map::find()而不是std::map::operator[],因为后者没有透明版本.