如何避免对地图访问进行常量转换?
How to avoid const cast for map access?
我有以下问题:
std::map<A*,double> map;
void getColor(A const * obj){
double d = map[obj]; // does not compile wihtout const_cast<A*>(obj)
// do something
}
我有一个映射 std::map
(某处),它存储指向对象 A
的指针。
我有一个函数 getColor
,它 不会 操作对象 A
,因此需要一个指向 const A
的指针作为输入。
如果不使用 const_cast,函数 getColor
将无法编译。
const 转换是一个设计问题,但如果我不想在map
中创建键,我不知道如何规避它const.
感谢任何帮助。
这里有两种可能的情况:
obj
的函数 knows/expects 已经存在于地图中,为了方便起见,您正在使用 []
。
您正在使用 []
以发挥其全部潜力,即您希望它将 obj
添加到地图(如果尚未存在)。
在情况 2 中,您的 getColor
签名有误。由于它可能会将 obj
传递到将其存储为 A*
的位置,因此仅接受 const A*
是错误的。请注意,即使函数不修改对象 本身 而是将其传递到可以修改的地方,它实际上是在间接修改它,因此应该将其视为非 const
.
情况一,取决于你的C++版本。 C++14 引入了 template overload of find
和 std::map
的相关成员函数,它采用 任何与 Key
相当的东西,而不仅仅是 Key
。因此,您可以像这样修改函数:
void getColor( A const * obj){
doubel d = map.find(obj)->second;
// do something
}
请注意,要使其正常工作,您还需要更改地图类型以使用透明比较器:std::map<A*,double, std::less<>> map;
(正如 最先指出的那样)。
如果您坚持使用 C++11 或更早版本,那您就倒霉了,您将不得不忍受 const_cast
。请注意,通过适当的注释,const_cast
在这种情况下是完全安全和可接受的(更不用说不更改 map
类型的唯一方法)。同样,您应该使用 find
或者 at
而不是 []
,因为您不想插入到地图中。
如果您负担得起切换到 C++14,那么您可以配置您的映射以使用 transparent comparator(这将起作用,因为可以将 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
}
请注意,您必须使用 std::map::find()
而不是 std::map::operator[]
,因为后者 .
我有以下问题:
std::map<A*,double> map;
void getColor(A const * obj){
double d = map[obj]; // does not compile wihtout const_cast<A*>(obj)
// do something
}
我有一个映射 std::map
(某处),它存储指向对象 A
的指针。
我有一个函数 getColor
,它 不会 操作对象 A
,因此需要一个指向 const A
的指针作为输入。
如果不使用 const_cast,函数 getColor
将无法编译。
const 转换是一个设计问题,但如果我不想在map
中创建键,我不知道如何规避它const.
感谢任何帮助。
这里有两种可能的情况:
obj
的函数 knows/expects 已经存在于地图中,为了方便起见,您正在使用[]
。您正在使用
[]
以发挥其全部潜力,即您希望它将obj
添加到地图(如果尚未存在)。
在情况 2 中,您的 getColor
签名有误。由于它可能会将 obj
传递到将其存储为 A*
的位置,因此仅接受 const A*
是错误的。请注意,即使函数不修改对象 本身 而是将其传递到可以修改的地方,它实际上是在间接修改它,因此应该将其视为非 const
.
情况一,取决于你的C++版本。 C++14 引入了 template overload of find
和 std::map
的相关成员函数,它采用 任何与 Key
相当的东西,而不仅仅是 Key
。因此,您可以像这样修改函数:
void getColor( A const * obj){
doubel d = map.find(obj)->second;
// do something
}
请注意,要使其正常工作,您还需要更改地图类型以使用透明比较器:std::map<A*,double, std::less<>> map;
(正如
如果您坚持使用 C++11 或更早版本,那您就倒霉了,您将不得不忍受 const_cast
。请注意,通过适当的注释,const_cast
在这种情况下是完全安全和可接受的(更不用说不更改 map
类型的唯一方法)。同样,您应该使用 find
或者 at
而不是 []
,因为您不想插入到地图中。
如果您负担得起切换到 C++14,那么您可以配置您的映射以使用 transparent comparator(这将起作用,因为可以将 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
}
请注意,您必须使用 std::map::find()
而不是 std::map::operator[]
,因为后者