コピー代入演算子、ムーブ代入演算子に加え、initializer_list 代入演算子の、計3種類を定義します。
template <typename T> class myvector { ... /** * @brief Copy assignment operator. Replaces the contents with a copy of the * contents of other. * @param[in] other: Another container to use as data source. * @return Own reference. * @throw std::bad_alloc: If malloc() (or realloc()) fails to allocate storage. */ self_type& operator=(const self_type& other) { if (this != &other) { // clear for (size_type i = 0; i < size_; i++) { heap_[i].~value_type(); } size_ = 0; // re-allocate if needed if (other.size() > capacity_) { reallocation(other.size(), realloc_switcher()); } // assign pointer p = heap_; for (auto i = other.cbegin(); i != other.cend(); ++i) { new(p++) value_type(*i); } size_ = other.size(); } return *this; } /** * @brief Move assignment operator. Replaces the contents with those of * other using move semantics (i.e. the data in other is moved from * other into this container). other is in a valid but unspecified * state afterwards. In any case, all elements originally present * in *this are either destroyed or replaced by element-wise move-assignment. * @param[in] other: Another container to use as data source. * @return Own reference. */ self_type& operator=(self_type&& other) noexcept { if (this != &other) { // clear for (size_type i = 0; i < size_; i++) { heap_[i].~value_type(); } size_ = 0; // swap std::swap(heap_, other.heap_); std::swap(size_, other.size_); std::swap(capacity_, other.capacity_); } return *this; } /** * @brief Replaces the contents with those identified by initializer list ilist. * @param[in] ilist: Initializer list to use as data source. * @return Own reference. * @throw std::length_error: If ilist size is greater than max_size(). * @throw std::bad_alloc: If malloc() (or realloc()) fails to allocate storage. */ self_type& operator=(std::initializer_list<value_type> ilist) { size_type new_size = length_check(ilist.size()); // clear for (size_type i = 0; i < size_; i++) { heap_[i].~value_type(); } size_ = 0; // re-allocate if needed if (new_size > capacity_) { reallocation(new_size, realloc_switcher()); } // assign pointer p = heap_; for (const auto& i: ilist) { new(p++) value_type(i); } size_ = ilist.size(); return *this; } ... };コピー代入演算子は、自己代入チェックを行った後、①clear()相当の処理、②必要なら領域拡張、③コピーコンストラクタでコピー、という処理を行います。
ムーブ代入演算子は、自己代入チェックを行った後、swap()相当の処理を行います。
initializer_listの代入演算子は、引数の長さチェックを行った後、①clear()相当の処理、②必要なら領域拡張、③コピーコンストラクタでコピー、という処理を行います。
いずれの代入演算子も、戻り値は自身の非const参照になります。
全ソースコード:
https://github.com/suomesta/myvector/tree/master/017
0 件のコメント:
コメントを投稿