Am 10.09.2015 um 23:11 schrieb Murray Cumming: > Now that our Glib::Objects and Gtk::Widgets are movable, so they can be > placed in standard containers, I guess we should implement swap() so the > standard containers can use that too. And maybe it's just generally good > practice to provide a swap() for all classes. Stop me at this point if > I'm wrong about that.
Sounds like a good idea. I've never had a deep look into the gtkmm sources, but I'd like to propose a completely different implementation of all these functions, which if applicable at all, are a bit shorter and easier. This is all based on the assumption that the classes we are talking about all only have a single member variable that is a pointer to the corresponding C structure, owned by these wrapper classes. If that's not the case, this whole proposal might not make sense. So, before even talking about the swap implementation, I would make one big change, which is to exchange these structs that are manually managed via pointers, new and delete with std::unique_ptr<StructName>. Apart from making the following function implementations a lot simpler, it would probably erase the need for an explicit destructor, and the move constructor and move assignment operator could be `= default`ed. > If we do want to provide swap() for these classes, I'd like to agree > about how best to implement them: > > We already have swap() for our boxed type classes, such as Gdk::Color. > We implement a member swap(): I agree, that makes sense. > void Color::swap(Color& other) noexcept > { > GdkColor *const temp = gobject_; > gobject_ = other.gobject_; > other.gobject_ = temp; > } With gobject_ being a std::unique_ptr<GdkColor> in this case, this could be simplified to: void Color::swap(Color& other) noexcept { gobject_.swap(other.gobject_); } > and we implement a standalone swap in our namespace, so that std::swap() > can use it. (See http://www.cplusplus.com/reference/utility/swap/ ) > We implement that standalone swap with our member swap(): > > inline void swap(Color& lhs, Color& rhs) noexcept > { lhs.swap(rhs); } Checked with cppreference.com, seems like the right way of doing thing (although it seems a bit weird to me that specializing std::swap isn't preferred over creating it in your own namespace, never heard about argument dependent lookup before). > At the moment we are using the member swap in our move assignment > operator and copy assignment operators (operator=): > > Color& Color::operator=(Color&& other) noexcept > { > Color temp(other); > swap(temp); > return *this; > } This would become: Color& Color::operator=(Color&& other) noexcept { gobject_ = std::move(other.gobject_); return *this; } > Color& Color::operator=(const Color& other) > { > Color temp(other); > swap(temp); > return *this; > } This implementation makes sense with or without changing the type of gobject_ as far as I can tell. > The member swap() is obviously useful for those operator=() > implementations, though I guess swap(*this, temp) would work too. If not changing the type of gobject_, that's what I'd do for the move assignment operator. > But the member swap() isn't inline so our standalone swap() isn't as > efficient as it could be. I heavily doubt that inline makes any difference in performance once you enable compiler optimizations. I think it doesn't have any real effect other than giving developers the ability to define functions in header files. > So: > Should we make our member swap() methods inline? Not for performance reasons, unless we want the best possible performance for users of very stupid compilers. > Should we not have member swap() methods and just use our standalone > swap() functions? I don't have a strong opinion on this, a friend function would work as well. I slightly prefer having member functions, for when you want to use them in application code. > And, should we implement swap() using std::swap() on the member > variables, or even std::move() on the member variables? Now after reading this question, I'm not sure anymore if my suggestion really makes no sense without changing the type of gobject_. Anyway, I don't see why you would do the swap manually, instead of through the standard library (if through std::swap or std::unique_ptr<T>::swap). _______________________________________________ gtkmm-list mailing list gtkmm-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtkmm-list