Reputation: 4954
According to SGI's doc on associative containers, "Since elements are stored according to their keys, it is essential that the key associated with each element is immutable". I sometimes use a pointer as a key to std::map, since, although the pointed object might be mutable, the pointer itself is constant.
QPointer is technically an object mimicking a pointer, and Qt's doc says that we can use QPointers exactly like pointers. Since the QPointer object itself may change during execution, can it still be used as the key to a std::map container?
Edit 1 : I can't use a QMap, I have to stick to std::map.
Edit 2 : The code compiles when I use a QPointer. The question is about whether I should expect unpleasant surprises at runtime.
Upvotes: 5
Views: 1232
Reputation: 72431
No, this is not safe, because QPointer<T>
may change to NULL
when a QObject
is destroyed. (QPointer
is similar to std::weak_ptr
.) So this code would produce Undefined Behavior:
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!
Upvotes: 7
Reputation: 881
It is undefined behavior to compare pointers from different allocation blocks for anything other than equality/inequality. I.e. After allocating a block with new or malloc, you can walk through the buffer and test if your pointer is less than the end of the buffer. But you can't do two separate news/mallocs and compare the resulting pointers for anything other than equality/inequality.
Well... you can but you may not like the results.
Upvotes: 0
Reputation: 363767
I take it (from the principle of least surprise) that a QPointer
won't "magically" change where it points if you don't reassign it and don't delete the underlying object, so it should be safe.
(I must add that I've seen Qt violate the principle of least surprise several times, so test to be sure.)
Upvotes: 0