在const函数中更改映射内容
Changing a map content inside const function
我使用QMap::find()
从const QMap
获得一个迭代器,并且通过该迭代器,我可以更改映射的内容。在我看来,这违反了对象的逻辑恒定性。我错了吗?
这是允许的,因为编译器不能识别什么被改变,因为Qt API?
void OpticalTrackingSystem::UpdateTrackability(const QUuid &uid) const
{
// m_ObjectsToTrack is a member, therefore const
ObjectMap::iterator it = m_ObjectsToTrack.find(uid);
it.value().m_Trackable = true; // assignment to const!
it.value().m_Moved = false;
}
如果有关系,我的编译器是MSVC。
Edit: ObjectMap
定义为
struct ObjectProperties
{
ObjectProperties(const ObjectToTrack &obj)
: m_Obj(obj) { m_Trackable = false; m_Moved = false; }
ObjectToTrack m_Obj;
bool m_Trackable;
bool m_Moved;
};
typedef QMap<QUuid, ObjectProperties> ObjectMap;
const增强了数据隐藏和封装功能,以提供完整的编译时安全性。
c++只支持一层常量。在您的示例中,这意味着您的函数不能添加、删除或替换映射中的元素。然而,操纵其成员是公平的游戏。
QMap
同时具有const和非const find
方法:
iterator find(const Key & key)
const_iterator find(const Key & key) const
就像std::map
:
iterator find (const key_type& k);
const_iterator find (const key_type& k) const;
QMap
迭代器在value()
的constness上有所不同:
T& QMap:: iterator::value() const;
const T& QMap::const_iterator::value() const;
所以不能通过返回的迭代器操作这些值。但是你将返回的迭代器赋值给ObjectMap::iterator
——我预计此时会出现错误,但是没有ObjectMap
及其迭代器的定义,我无法测试它。
显然下面的MCVE演示了一个编译时错误:
#include <QMap>
int main()
{
const QMap<int,float> m{{1, 1.0}, {5, 5.0}};
auto it = m.find(1);
it.value() = 2.0;
// ^
// error: assignment of read-only location
// ‘it.QMap<Key, T>::const_iterator::value<int, float>()’
}
显式地赋值迭代器会给出另一个预期错误:
#include <QMap>
int main()
{
const QMap<int,float> m{{1, 1.0}, {5, 5.0}};
QMap<int,float>::iterator it = m.find(1);
// ^
// error: conversion from ‘QMap<int, float>::const_iterator’
// to non-scalar type ‘QMap<int, float>::iterator’ requested
it.value() = 2.0;
}
(我在两种情况下都使用g++ -std=c++11 -Wall -Wextra -fPIC $(pkg-config --cflags Qt5Core)
编译)
编辑
由于问题中没有适当的示例,我试图推断缺失的声明。但是当我尝试编译这个时,我仍然从gcc得到所需的错误:
#include <QMap>
#include <QUuid>
struct ObjectToTrack
{
};
struct ObjectProperties
{
ObjectProperties(const ObjectToTrack &obj)
: m_Obj(obj), m_Trackable(), m_Moved() {}
ObjectToTrack m_Obj;
bool m_Trackable;
bool m_Moved;
};
typedef QMap<QUuid, ObjectProperties> ObjectMap;
struct OpticalTrackingSystem
{
ObjectMap m_ObjectsToTrack;
void UpdateTrackability(const QUuid &uid) const;
};
void OpticalTrackingSystem::UpdateTrackability(const QUuid &uid) const
{
ObjectMap::iterator it = m_ObjectsToTrack.find(uid);
// ^
// error: conversion from ‘QMap<QUuid, ObjectProperties>::const_iterator’ to
// non-scalar type ‘QMap<QUuid, ObjectProperties>::iterator’ requested
it.value().m_Trackable = true;
it.value().m_Moved = false;
}
我的结论是问题中的代码没有问题。要么是编译器有bug,要么是问题中缺少了与我上面的重构不同的重要信息。
相关文章:
- 使用 const char* 键映射 C++ 检索空值
- 使用 const char* 作为映射/unordered_map的键
- 将引用对具有shared_ptr作为值的映射转换为对具有shared_ptr const 作为值的映射的引用
- 作为映射键的对象在CPP中变为const
- 从 Java 调用C++函数。映射"const char*"
- 哈希映射错误:与调用 '(const __gnu_cxx::.
- C++ - 映射 - 错误:请求"w"中的成员'first',该成员属于非类类型 'const int'
- 如何将const std::shared_ptr插入到std::映射中
- 使用JNA将const char**映射到Java类型
- 如何在const方法中迭代映射
- 如何将const_cast的const指针向量映射到非常量指针向量
- 在STXXL映射中使用const char*
- C++从const函数调用指向具有映射的成员的指针
- Pair(const std::p air<_T1, _T2>&) 被隐式删除,因为默认定义格式不正确 错误:分配unique_ptr映射时
- c++模板类静态const变量成员作为映射键给出未定义引用
- c++中使用const char*作为映射键的正确方法
- 在const函数中更改映射内容
- C++ 映射/设置迭代器不可取消引用 --- map<const char *,字符串>
- 可以将非const值类型的映射强制转换为const值类型的映射吗?
- c++嵌套映射不匹配成员函数const成员