Search code examples
c++mfc

MFC - CArray copy


I have two arrays filled with integers.

The equal operator can not be used as the compiler is giving one error.

The source code is below. Please help.

CArray <int, int&> temp;
CArray <int, int&> definition;
    
definition = temp;

The error is the following:

error C2280: CArray<int,int &> &CArray<int,int &>::operator =(const CArray<int,int &> &): attempting to reference a deleted function


Solution

  • The CArray class template derives from CObject. The latter declares its copy constructor and assignment operator as private, and CArray necessarily inherits those properties. Any attempt to use either results in compiler error C2280.

    CArray, however, provides the public Copy() member that copies data from a CArray instance into the CArray instance on which it is called.

    Replacing

    definition = temp;
    

    with

    definition.Copy(temp);
    

    fixes the compiler error and copies values from temp into definition. Following this line of code, definition and temp hold the same data.


    Improving ergonomics

    Modulo the ambiguity (does Copy() copy from, or into the left-hand side?), there's nothing wrong with explicitly invoking the class member. Ideally, though, it should be possible to augment the interface of a foreign type with custom functionality to allow writing concise code.

    Free functions have long been the go-to solution for this in C++, and operators are no exception. Still, for reasons unknown to me, C++ does not allow providing an assignment operator (operator=) as a free function.

    It does allow externally supplying all "compound" assignment operators as free functions, though (such as operator+=). With that, we can get close to what we want to write by introducing this:

    template<typename T, typename U>
    inline CArray<T, U>& operator+=(CArray<T, U>& dst, CArray<T, U> const& src)
    {
        dst.Append(src);
        return dst;
    }
    

    With this function template, we can write

    definition += temp;
    

    and at least eliminate the ambiguity by mapping to the conventional lhs/rhs dichotomy prevalent in C-like languages. This implements "append" functionality (not "copy"). To make "append" and "copy" behave identically, the left-hand side needs to be empty. Call RemoveAll() beforehand to establish this precondition, if required.

    This is not ideal, but at least it is something. It is the best we can do (at the time of writing) without introducing a new type (e.g. by deriving from the CArray class template).