views:

93

answers:

3

I was reading some boost code, and came across this:

inline sparse_vector &assign_temporary(sparse_vector &v) {
    swap(v);
    return *this;
}
template<class AE>
    inline sparse_vector &operator=(const sparse_vector<AE> &ae) {
        self_type temporary(ae);
        return assign_temporary(temporary);
    }

It seems to be mapping all of the constructors to assignment operators. Great. But why did C++ ever opt to make them do different things? All I can think of is scoped_ptr?

+2  A: 

Notice the name "assign_temporary" indicates that the assignment is from an object that is temporary and therefore can be destroyed in the process of assignment. The assignment operator takes some regular object that you might want to use later, so it is not an option to destroy it during the assignment. In this Boost code, "assign_temporary" is synonymous with the rvalue reference assignment operator, while the assignment operator that you have shown above is the standard const (lvalue) reference assignment operator, so you would, therefore, expect this kind of mismatch between the two.

I agree, though, the assignment operator is typically implemented using the copy and swap trick (create a copy with the copy constructor, then swap with the copy). However, the standard already defines the automatic implementation of the assignment operator by the compiler in the absence of an explicit definition, and so changing the default implementation would potentially break existing code.

Michael Aaron Safyan
+5  A: 

why did C++ ever opt to make them do different things?

Because assignment works on a fully constructed object. In resource managing classes, this means that every member pointer already points to a resource. Contrast this to a constructor, where the members don't have any meaning prior to executing it.

By the way, in the very early days of C++, T a(b); was actually defined as T a; a = b;, but this proved to be inefficient, hence the introduction of the copy constructor.

FredOverflow
+1  A: 

For the very reason that some classes sometimes shouldn't be allowed to be assigned or even copied. For instance, using RAII you can build a mutex class which opens a lock and then closes the lock upon expiration. If you were allowed to copy or assign such a class you could conceivably pass it outside of the function scope. This could cause bad things in the hands of bad people.

wheaties