QPointer可以成为std :: map的关键

Fre*_*red 4 c++ qt stl qpointer

根据SGI关于关联容器的文档,"由于元素是根据其键存储的,因此与每个元素相关联的键必须是不可变的".我有时使用指针作为std :: map的键,因为虽然指向的对象可能是可变的,但指针本身是常量.

QPointer在技术上是一个模仿指针的对象,Qt的doc说我们可以像指针一样使用QPointers.由于QPointer对象本身可能在执行期间发生变化,它仍然可以用作std :: map容器的键吗?

编辑1:我不能使用QMap,我必须坚持使用std :: map.
编辑2:当我使用QPointer时代码编译.问题是我是否应该在运行时期待令人不快的意外.

asc*_*ler 7

不,这不安全,因为QPointer<T>可能会NULL在a QObject被破坏时改变.(QPointer类似于std::weak_ptr.)所以这段代码会产生未定义的行为:

class CopyableWidget : public QWidget {
  Q_OBJECT;
public:
  CopyableWidget(Widget* parent = 0) : QWidget(parent) {}
  CopyableWidget(const CopyableWidget& w, Widget* parent = 0) : QWidget(parent) {}
};

std::vector<CopyableWidget> v(2); // Two default-constructed widgets
std::map<QPointer<CopyableWidget>, int> wid_values;
wid_values[&v[0]] = 1;
wid_values[&v[1]] = 2;
// wid_values contains { {&v[0], 1}, {&v[1], 2} }
v.resize(1);
// The QPointer in wid_values constructed from &v[1] now acts like NULL.
// wid_values contains { {&v[0], 1}, {NULL, 2} }
// But &v[0] > NULL (on most platforms). Class invariant was violated!
Run Code Online (Sandbox Code Playgroud)