コピー代入演算子、ムーブ代入演算子に加え、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 件のコメント:
コメントを投稿