After some experimentation with move semantics with the created array type, I wonder why the Microsoft C ++ compiler calls the move constructor when it returns from the method by value, while the Clang compiler returns a copy together?
Is this the right or wrong behavior from Clang? or the right behavior from Microsoft?
#include <algorithm> #include <iostream> template<typename T> class Array { public: template<typename E> class ArrayIterator { public: ArrayIterator(Array<E>& elements, int index) : position_(index), elements_(elements) { } T& operator * () { return elements_[position_]; } ArrayIterator& operator++ () { position_++; return *this; } ArrayIterator operator++ (int) { return ArrayIterator(elements_, ++position_); } bool operator != (ArrayIterator const & other) { return position_ != other.position_; } private: int position_; Array<E>& elements_; }; typedef ArrayIterator<T> iterator; Array(); explicit Array(int size); ~Array(); Array(const Array& other); Array(Array&& other); Array<T>& operator = (Array other); T& operator[](int index); int size() const; iterator begin(); iterator end(); private: void internal_swap(Array& other); T *elements_; int length_; }; template<typename T> Array<T>::Array() { length_ = 0; elements_ = 0; } template<typename T> Array<T>::Array(int size) { elements_ = new T[size]; length_ = size; } template<typename T> Array<T>::~Array() { delete[] elements_; std::cout << "Destroy...." << std::endl; } template<typename T> Array<T>::Array(const Array<T>& other) { std::cout << "copy ctor" << std::endl; length_ = other.size(); T *elements = new T[size()]; std::copy(other.elements_, other.elements_ + other.size(), elements); elements_ = elements; } template<typename T> Array<T>::Array(Array<T>&& other) { std::cout << "move ctor" << std::endl; length_ = other.size(); T* oelements = other.elements_; other.elements_ = 0; this->elements_ = oelements; } template<typename T> Array<T>& Array<T>::operator = (Array other) { internal_swap(other); return *this; } template<typename T> T& Array<T>::operator[](int index) { return elements_[index]; } template<typename T> int Array<T>::size() const { return length_; } template<typename T> typename Array<T>::iterator Array<T>::begin() { return iterator(*this, 0); } template<typename T> typename Array<T>::iterator Array<T>::end() { return iterator(*this, size()); }; template<typename T> void Array<T>::internal_swap(Array& other){ T* oelements = other.elements_; other.elements_ = this->elements_; this->elements_ = oelements; } Array<int> get_values(int x); int main(int argc, const char *argv[]) { Array<int> a = get_values(2); for (Array<int>::iterator i = a.begin(); i != a.end(); ++i) { std::cout << *i << std::endl; } return 0; } Array<int> get_values(int x) { Array<int> a(10); if(x == 1) return a; for (int i = 0; i <= 9; i++) { a[i] = 1 + i; } return a; }
source share