GNOME Bugzilla – Bug 626858
Glib::RefPtr<T> can't be used in std::set
Last modified: 2016-04-10 14:08:05 UTC
Created attachment 167816 [details] [review] implement relational operators for Glib::RefPtr std::map<Glib::RefPtr<T> > compiles, but doesn't work. The reason is that std::map needs an ordering on its key_type. RefPtr<T> doesn't define any relational operators beyond == and !=, but as it defines operator bool(), an attempt to compare two instances of a RefPtr<T>, e.g. p1 REL_OP p2 (with REL_OP being one of <, <=, >, >=), compiles. But it behaves oddly, as it in fact does (bool)p1 REL_OP (bool)p2. This in turn breaks std::map and other sorted containers. Attached is a patch that implements operators <, <=, >, >= for RefPtr<T>.
I meant std::set throught the bugreport. Sorry for the confusion. But it should break for std::map in the same way.
OK. I've heard that we should generally provide operator void*() instead of operator bool(), so that would also fix this. But we can't do that until we break API/ABI for glibmm. So in the meantime, I guess this is best. Thanks. Pushed. Sorry for the delay.
In gtkmm I have changed the operator bool() to operator const void*(), though I can't do that in glibmm yet until we break ABI. However, I currently only returning (void*) and (void*)1. These operator <(), etc, wpould be still necessary, right?
In C++11 we can use operator bool() again, with the explicit keyword. We should do that if we can do it without breaking ABI.
I have made our operator bool()s explicit in glibmm: https://git.gnome.org/browse/glibmm/commit/?id=aee3a6fa6a37e1178b43437966b4225a34f9c6e2 https://git.gnome.org/browse/glibmm/commit/?id=e70ea7f26327c4a872e5f6b6b83fd3fdd26434ce We still need to look at the "operator BoolExpr"s in glibmm and gtkmm.
I've also replaced the "operator BoolExpr" in glibmm: https://git.gnome.org/browse/glibmm/commit/?id=35af42466f6b36fe222b2e7a80589ff12004b1f8
And in gtkmm.