dav*_*dav 3 c++ pointers vector map
我有一个矢量映射对的映射,如下所示:
std::map<std::pair<uint16, uint16>, std::vector<std::vector<uint32> > >
Run Code Online (Sandbox Code Playgroud)
地图填充在类的构造函数中.这个类提供了一个返回指向std::vector<std::vector<uint32> >
(映射值部分)的指针的公共方法,如下所示:
typedef std::pair<uint16, uint16> key;
typedef std::vector<std::vector<uint32> > value;
value* FindValues(key someKey) {
std::map<key, value>::const_iterator it;
it = someStore.find(someKey);
if (it != someStore.end())
return &(value)it->second;
return NULL;
}
Run Code Online (Sandbox Code Playgroud)
这是奇怪的时候.迭代FindValues返回的向量时,所有子向量都有一个大的负数(例如-1818161232)作为它们的第一个值.但是,如果我使用如下函数:
value FindValues(key someKey) {
std::map<key, value>::const_iterator it;
return someStore.find(someKey)->second;
}
Run Code Online (Sandbox Code Playgroud)
......那么价值是正常的.这仅发生在所有子向量的索引0处的值.但是,使用第二种方法,如果找不到密钥,我的应用程序会出现段错误(原因很明显).我究竟做错了什么?
如果return语句看起来真的如此
return &(value) it->second;
Run Code Online (Sandbox Code Playgroud)
然后有几件事可以说:
如果编译器在没有发出诊断消息的情况下接受它就会中断.在C++中,将内置的一元&
应用于非引用的结果是非法的.该(value) it->second
表达式生成一个临时对象,即一个右值.您无法使用获取此类对象的地址&
.代码甚至不应该编译.
如果您的编译器接受它作为某种奇怪的"扩展",那么这意味着您确实获取并返回临时对象的地址.然后立即销毁临时对象,使指针指向垃圾.难怪你通过这样的指针看到一些奇怪的值.
由于您曾经const_iterator
存储过搜索结果这一事实,因此需要某种类型的转换.显然你做了一个被误导的企图抛弃it->second
你的(value)
演员的常数.正确的方法可能如下所示
return const_cast<value *>(&it->second);
Run Code Online (Sandbox Code Playgroud)
但是你为什么一开始就使用const_iterator
它?正确的做法是使用常规iterator
做法
return &it->second;
Run Code Online (Sandbox Code Playgroud)
没有任何额外的演员.
您需要决定FindValue
尝试编写哪种方法.如果这应该是一个常量方法,它应该返回const value *
并应该声明为const
const value* FindValues(key someKey) const
Run Code Online (Sandbox Code Playgroud)
当然,const_iterator
在这种情况下你应该使用内部.
如果您FindValue
应该是非常量方法,那么您可以保留当前声明
value* FindValues(key someKey)
Run Code Online (Sandbox Code Playgroud)
但使用普通的iterator
内部.
你现在拥有的是两者的某种混合体,这就是让你诉诸怪异演员阵容的原因.(事实上,你的课程可能需要两个版本.一个可以通过另一个实现.)
归档时间: |
|
查看次数: |
988 次 |
最近记录: |