1

Possible Duplicate:
Can someone please explain move semantics to me?

Consider the following example code of a constant-size mathematical array :

// INCLUDE
#include <iostream>
#include <initializer_list>

// BASE ARRAY
template<class T, unsigned int TSIZE> class BaseArray
{
    public:
    // Constructor
        inline BaseArray() : _data{}
        {
            std::cout<<"BaseArray::BaseArray()"<<std::endl;
        }

    // Copy constructor
        template<class T0> inline BaseArray(const BaseArray<T0, TSIZE> &rhs)
        {
            std::cout<<"BaseArray::BaseArray(const BaseArray<T0, TSIZE> &rhs)"<<std::endl;
            for(unsigned int i = 0; i < TSIZE; ++i) {
                _data[i] = rhs[i];
            }
        }

    // Initializer list constructor
        template<class T0> inline BaseArray(const std::initializer_list<T0>& rhs)
        {
            std::cout<<"BaseArray::BaseArray(const std::initializer_list<T0>& rhs)"<<std::endl;
            const T0* it = rhs.begin();
            for (unsigned int i = 0; i < TSIZE; ++i) {
                _data[i] = *it;
                ++it;
            }
        }

    // Destructor
        inline ~BaseArray()
        {
            std::cout<<"BaseArray::~BaseArray()"<<std::endl;
        }

    // Subscript operator
        inline const T& operator[](const unsigned int i) const
        {
            std::cout<<"BaseArray::operator[](const unsigned int i) const"<<std::endl;
            return _data[i];
        }
        inline T& operator[](const unsigned int i)
        {
            std::cout<<"BaseArray::operator[](const unsigned int i)"<<std::endl;
            return _data[i];
        }

    // Assignment operator
        template<class T0> inline BaseArray<T, TSIZE>& operator=(const BaseArray<T0, TSIZE>& rhs)
        {
            std::cout<<"BaseArray::operator=(const BaseArray<T0, TSIZE>& rhs)"<<std::endl;
            for (unsigned int i = 0; i < TSIZE; ++i) {
                _data[i] = rhs[i];
            }
            return *this;
        }

    // Sum assignment operator
        template<class T0> inline BaseArray<T, TSIZE>& operator+=(const BaseArray<T0, TSIZE>& rhs)
        {
            std::cout<<"BaseArray::operator+=(const BaseArray<T0, TSIZE>& rhs)"<<std::endl;
            for (unsigned int i = 0; i < TSIZE; ++i) {
                _data[i] += rhs[i];
            }
            return *this;
        }

    // Sum operator
        template<class T0> inline BaseArray<typename std::common_type<T, T0>::type, TSIZE> operator+(const BaseArray<T0, TSIZE>& rhs) const
        {
            std::cout<<"BaseArray::operator+(const BaseArray<T0, TSIZE>& rhs)"<<std::endl;
            return BaseArray<typename std::common_type<T, T0>::type, TSIZE>(*this) += rhs;
        }

    // Data members
    protected:
        T _data[TSIZE];
};

// MAIN
int main()
{
    BaseArray<double, 3> a({1., 2., 3.});
    BaseArray<double, 3> b({4., 5., 6.});
    BaseArray<double, 3> c({7., 8., 9.});
    BaseArray<double, 3> x;
    std::cout<<"------------------------------------------------------------"<<std::endl;
    x = a+b+c;
    std::cout<<"------------------------------------------------------------"<<std::endl;
    return 0;
}

It produces the output :

BaseArray::BaseArray(const std::initializer_list<T0>& rhs)
BaseArray::BaseArray(const std::initializer_list<T0>& rhs)
BaseArray::BaseArray(const std::initializer_list<T0>& rhs)
BaseArray::BaseArray()
------------------------------------------------------------
BaseArray::operator+(const BaseArray<T0, TSIZE>& rhs)
BaseArray::operator+=(const BaseArray<T0, TSIZE>& rhs)
BaseArray::operator[](const unsigned int i) const
BaseArray::operator[](const unsigned int i) const
BaseArray::operator[](const unsigned int i) const
BaseArray::~BaseArray()
BaseArray::operator+(const BaseArray<T0, TSIZE>& rhs)
BaseArray::operator+=(const BaseArray<T0, TSIZE>& rhs)
BaseArray::operator[](const unsigned int i) const
BaseArray::operator[](const unsigned int i) const
BaseArray::operator[](const unsigned int i) const
BaseArray::~BaseArray()
BaseArray::~BaseArray()
BaseArray::~BaseArray()
------------------------------------------------------------
BaseArray::~BaseArray()
BaseArray::~BaseArray()
BaseArray::~BaseArray()
BaseArray::~BaseArray()

Process returned 0 (0x0)   execution time : 0.015 s
Press any key to continue.

I've heard of "move semantics" and "move constructors" of C++2011 and I wonder if there is a way to avoid some temporaries with that in this code. Is it true or not ?

If it is possible, how to do it (if someone could write an example it would be great because I don't undestrand clearly the documentation I find on move semantics)?

Community
  • 1
  • 1
Vincent
  • 57,703
  • 61
  • 205
  • 388
  • 5
    The good folks here already poured lots of effort into explaining this topic. Have you searched around SO (in particular, the [tag:move-semantics] tag and [this question](http://stackoverflow.com/questions/3106110/can-someone-please-explain-move-semantics-to-me))? – R. Martinho Fernandes Aug 01 '12 at 15:09
  • 5
    Move semantics won't do much here, since your class contains a built-in array, which can be copied, but moving it makes no sense. – mfontanini Aug 01 '12 at 15:12
  • @mfontanini You can still move the individual elements of the array. – fredoverflow Aug 01 '12 at 17:20
  • @FredOverflow you're right ;), though OP won't see any optimizations when moving doubles, as in his example code. – mfontanini Aug 01 '12 at 17:44
  • @mfontanini well, the class is still generic. –  Aug 01 '12 at 19:04

0 Answers0