lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Confusion about any_member<> assignment operator (+PATCH)


From: Vadim Zeitlin
Subject: Re: [lmi] Confusion about any_member<> assignment operator (+PATCH)
Date: Fri, 27 Feb 2015 17:19:38 +0100
Date: Fri, 27 Feb 2015 15:05:51 +0100

On Thu, 19 Feb 2015 01:13:11 +0100 I wrote:

Me>  So I'd like to ask for your help here. Is any_member<> supposed to be
Me> value-like or pointer-like? Forgetting about the optimizations which led me
Me> to this originally, I think it's important to clear up the confusion with
Me> it being (or not) "Assignable": right now it definitely isn't, and the
Me> simplest solution is, of course, to just remove the comment saying that it
Me> is, but having an operator[] which doesn't accept all objects is pretty
                      ^^^^^^^^^^
 This was supposed to be "operator=", sorry.
        
Me> unusual in not a good way too IMO.

 I still think that any_member<> assignment semantics are confusing, but I
finally realized that I didn't actually need to deal with the assignment at
all. While formally speaking an object must be assignable in order to be
used in a standard container in C++98, in practice, and also in C++11, this
is not actually necessary if no operations resulting in moving the elements
around are used. Of course, something is required in order to be able to do
anything other than appending elements to the vector and in C++11 this
"something" is the "Swappable" requirement and while this is not directly
supported by the C++98 std::vector<> implementation used by, I can still
achieve everything I need with just a working swap.

 Right now calling swap() free function on two any_member<> objects doesn't
work correctly neither however. I could avoid it by using swap() member,
but I hope that the following trivial patch allowing to use just swap()
could be applied instead:
---------------------------------- >8 --------------------------------------
commit d05ea8ef5cf6c94e421b04c582fa0a86c25076db
Author: Vadim Zeitlin <address@hidden>
Date:   Fri Feb 27 14:52:53 2015 +0100

    Define global swap() for any_member<>.
    
    The default std::swap() implementation doesn't work for swapping arbitrary
    any_member<> objects as it relies on being able to assign them, but this is
    impossible with any_member<> which has a non-standard assignment semantics 
and
    only supports assigning between objects of the same type. However swapping 
two
    any_member<> objects, of whatever types, is perfectly possible, so provide
    swap() overload allowing to do this.
    
    Notice that std::swap() can't be overloaded, hence we this swap() function
    must be defined in the same namespace as any_member<> itself, i.e. the 
global
    one.

diff --git a/any_member.hpp b/any_member.hpp
index 4601e9f..70a9e18 100644
--- a/any_member.hpp
+++ b/any_member.hpp
@@ -403,6 +403,16 @@ any_member<ClassType>& 
any_member<ClassType>::assign(std::string const& s)
     return *this;
 }
 
+/// The standard implementation of swap() doesn't work for any_member<> as it
+/// doesn't allow swapping the members of different types, so this is more than
+/// optimization: providing this specialization is required for e.g. storing
+/// the objects of this class in standard containers.
+template <typename ClassType>
+void swap(any_member<ClassType>& left, any_member<ClassType>& right)
+{
+    left.swap(right);
+}
+
 /// Definition of class template reconstitutor.
 ///
 /// Class template reconstitutor matches pointer-to-member types.
---------------------------------- >8 --------------------------------------

 Would you mind applying this please?

 Nothing more is, strictly speaking, needed any more right now, although I
continue to believe that it would be better to do something about
any_member<> assignment semantics which is really pretty confusing right
now.

 Thanks in advance,
VZ


reply via email to

[Prev in Thread] Current Thread [Next in Thread]