使用C++17标准 手写一个vector
#include <iostream>
#include <memory>
#include <initializer_list>
#include <algorithm>
#include <stdexcept>
#include <type_traits>template<typename T>
class Vector {
public:using value_type = T;using size_type = std::size_t;using difference_type = std::ptrdiff_t;using reference = T&;using const_reference = const T&;using pointer = T*;using const_pointer = const T*;using iterator = T*;using const_iterator = const T*;using reverse_iterator = std::reverse_iterator<iterator>;using const_reverse_iterator = std::reverse_iterator<const_iterator>;Vector() noexcept : m_data(nullptr), m_size(0), m_capacity(0) {}explicit Vector(size_type count) : m_data(nullptr), m_size(0), m_capacity(0) {resize(count);}Vector(size_type count, const T& value) : m_data(nullptr), m_size(0), m_capacity(0) {resize(count, value);}template<typename InputIt>Vector(InputIt first, InputIt last) : m_data(nullptr), m_size(0), m_capacity(0) {assign(first, last);}Vector(std::initializer_list<T> init) : m_data(nullptr), m_size(0), m_capacity(0) {assign(init);}Vector(const Vector& other) : m_data(nullptr), m_size(0), m_capacity(0) {if (other.m_size > 0) {reserve(other.m_size);std::uninitialized_copy(other.begin(), other.end(), m_data);m_size = other.m_size;}}Vector(Vector&& other) noexcept: m_data(other.m_data), m_size(other.m_size), m_capacity(other.m_capacity) {other.m_data = nullptr;other.m_size = 0;other.m_capacity = 0;}~Vector() {clear();::operator delete(m_data, std::align_val_t(alignof(T)));}Vector& operator=(const Vector& other) {if (this != &other) {Vector tmp(other);swap(tmp);}return *this;}Vector& operator=(Vector&& other) noexcept {if (this != &other) {clear();::operator delete(m_data, std::align_val_t(alignof(T)));m_data = other.m_data;m_size = other.m_size;m_capacity = other.m_capacity;other.m_data = nullptr;other.m_size = 0;other.m_capacity = 0;}return *this;}Vector& operator=(std::initializer_list<T> init) {assign(init);return *this;}reference operator[](size_type pos) {return m_data[pos];}const_reference operator[](size_type pos) const {return m_data[pos];}reference at(size_type pos) {if (pos >= m_size) {throw std::out_of_range("Vector::at - index out of range");}return m_data[pos];}const_reference at(size_type pos) const {if (pos >= m_size) {throw std::out_of_range("Vector::at - index out of range");}return m_data[pos];}reference front() {return m_data[0];}const_reference front() const {return m_data[0];}reference back() {return m_data[m_size - 1];}const_reference back() const {return m_data[m_size - 1];}pointer data() noexcept {return m_data;}const_pointer data() const noexcept {return m_data;}iterator begin() noexcept {return m_data;}const_iterator begin() const noexcept {return m_data;}const_iterator cbegin() const noexcept {return m_data;}iterator end() noexcept {return m_data + m_size;}const_iterator end() const noexcept {return m_data + m_size;}const_iterator cend() const noexcept {return m_data + m_size;}reverse_iterator rbegin() noexcept {return reverse_iterator(end());}const_reverse_iterator rbegin() const noexcept {return const_reverse_iterator(end());}const_reverse_iterator crbegin() const noexcept {return const_reverse_iterator(cend());}reverse_iterator rend() noexcept {return reverse_iterator(begin());}const_reverse_iterator rend() const noexcept {return const_reverse_iterator(begin());}const_reverse_iterator crend() const noexcept {return const_reverse_iterator(cbegin());}bool empty() const noexcept {return m_size == 0;}size_type size() const noexcept {return m_size;}size_type capacity() const noexcept {return m_capacity;}void reserve(size_type new_cap) {if (new_cap > m_capacity) {pointer new_data = static_cast<pointer>(::operator new(new_cap * sizeof(T), std::align_val_t(alignof(T))));size_type i = 0;try {for (; i < m_size; ++i) {if constexpr (std::is_nothrow_move_constructible_v<T> ||!std::is_copy_constructible_v<T>) {new (&new_data[i]) T(std::move(m_data[i]));}else {new (&new_data[i]) T(m_data[i]);}}}catch (...) {for (size_type j = 0; j < i; ++j) {new_data[j].~T();}::operator delete(new_data, std::align_val_t(alignof(T)));throw;}for (size_type i = 0; i < m_size; ++i) {m_data[i].~T();}::operator delete(m_data, std::align_val_t(alignof(T)));m_data = new_data;m_capacity = new_cap;}}void shrink_to_fit() {if (m_capacity > m_size) {Vector tmp(*this);swap(tmp);}}void clear() noexcept {for (size_type i = 0; i < m_size; ++i) {m_data[i].~T();}m_size = 0;}iterator insert(const_iterator pos, const T& value) {return emplace(pos, value);}iterator insert(const_iterator pos, T&& value) {return emplace(pos, std::move(value));}iterator insert(const_iterator pos, size_type count, const T& value) {difference_type offset = pos - begin();if (count == 0) {return begin() + offset;}if (m_size + count > m_capacity) {reserve(std::max(m_size + count, m_capacity * 2));}iterator insert_pos = begin() + offset;for (auto it = end() + count - 1; it >= insert_pos + count; --it) {if (it < end()) {*it = std::move(*(it - count));}else {new (it) T(std::move(*(it - count)));}}for (size_type i = 0; i < count; ++i) {if (insert_pos + i < end()) {*(insert_pos + i) = value;}else {new (insert_pos + i) T(value);}}m_size += count;return insert_pos;}template<typename InputIt>iterator insert(const_iterator pos, InputIt first, InputIt last) {difference_type offset = pos - begin();size_type count = std::distance(first, last);if (count == 0) {return begin() + offset;}if (m_size + count > m_capacity) {reserve(std::max(m_size + count, m_capacity * 2));}iterator insert_pos = begin() + offset;for (auto it = end() + count - 1; it >= insert_pos + count; --it) {if (it < end()) {*it = std::move(*(it - count));}else {new (it) T(std::move(*(it - count)));}}size_type i = 0;try {for (; first != last; ++first, ++i) {if (insert_pos + i < end()) {*(insert_pos + i) = *first;}else {new (insert_pos + i) T(*first);}}}catch (...) {for (size_type j = 0; j < i; ++j) {(insert_pos + j)->~T();}for (auto it = insert_pos + count; it != end() + count; ++it) {if (it < end()) {*it = std::move(*(it + count));}}throw;}m_size += count;return insert_pos;}iterator insert(const_iterator pos, std::initializer_list<T> init) {return insert(pos, init.begin(), init.end());}template<typename... Args>iterator emplace(const_iterator pos, Args&&... args) {difference_type offset = pos - begin();if (m_size == m_capacity) {reserve(m_capacity == 0 ? 1 : m_capacity * 2);}iterator insert_pos = begin() + offset;if (insert_pos != end()) {new (end()) T(std::move(back()));for (auto it = end() - 1; it > insert_pos; --it) {*it = std::move(*(it - 1));}*insert_pos = T(std::forward<Args>(args)...);}else {new (insert_pos) T(std::forward<Args>(args)...);}++m_size;return insert_pos;}iterator erase(const_iterator pos) {return erase(pos, pos + 1);}iterator erase(const_iterator first, const_iterator last) {if (first == last) {return begin() + (first - begin());}difference_type count = last - first;iterator first_it = begin() + (first - begin());iterator last_it = begin() + (last - begin());for (auto it = last_it; it != end(); ++it) {*(it - count) = std::move(*it);}for (auto it = end() - count; it != end(); ++it) {it->~T();}m_size -= count;return first_it;}void push_back(const T& value) {emplace_back(value);}void push_back(T&& value) {emplace_back(std::move(value));}template<typename... Args>reference emplace_back(Args&&... args) {if (m_size == m_capacity) {reserve(m_capacity == 0 ? 1 : m_capacity * 2);}new (m_data + m_size) T(std::forward<Args>(args)...);++m_size;return back();}void pop_back() {if (m_size > 0) {back().~T();--m_size;}}void resize(size_type count) {resize(count, T());}void resize(size_type count, const T& value) {if (count > m_size) {reserve(count);for (size_type i = m_size; i < count; ++i) {new (m_data + i) T(value);}}else if (count < m_size) {for (size_type i = count; i < m_size; ++i) {m_data[i].~T();}}m_size = count;}void swap(Vector& other) noexcept {std::swap(m_data, other.m_data);std::swap(m_size, other.m_size);std::swap(m_capacity, other.m_capacity);}template<typename InputIt>void assign(InputIt first, InputIt last) {clear();reserve(std::distance(first, last));for (; first != last; ++first) {emplace_back(*first);}}void assign(size_type count, const T& value) {clear();reserve(count);for (size_type i = 0; i < count; ++i) {emplace_back(value);}}void assign(std::initializer_list<T> init) {assign(init.begin(), init.end());}private:T* m_data;size_type m_size;size_type m_capacity;
};
template<typename T>
bool operator==(const Vector<T>& lhs, const Vector<T>& rhs) {if (lhs.size() != rhs.size()) {return false;}return std::equal(lhs.begin(), lhs.end(), rhs.begin());
}template<typename T>
bool operator!=(const Vector<T>& lhs, const Vector<T>& rhs) {return !(lhs == rhs);
}template<typename T>
bool operator<(const Vector<T>& lhs, const Vector<T>& rhs) {return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}template<typename T>
bool operator<=(const Vector<T>& lhs, const Vector<T>& rhs) {return !(rhs < lhs);
}template<typename T>
bool operator>(const Vector<T>& lhs, const Vector<T>& rhs) {return rhs < lhs;
}template<typename T>
bool operator>=(const Vector<T>& lhs, const Vector<T>& rhs) {return !(lhs < rhs);
}template<typename T>
void swap(Vector<T>& lhs, Vector<T>& rhs) noexcept {lhs.swap(rhs);
}
int main() {Vector<int> vec;for (int i = 0; i < 10; ++i) {vec.push_back(i);}std::cout << "Vector elements: ";for (const auto& val : vec) {std::cout << val << " ";}std::cout << std::endl;vec.insert(vec.begin() + 5, 99);std::cout << "After insertion: ";for (const auto& val : vec) {std::cout << val << " ";}std::cout << std::endl;vec.erase(vec.begin() + 5);std::cout << "After deletion: ";for (const auto& val : vec) {std::cout << val << " ";}std::cout << std::endl;Vector<int> vec2 = vec;std::cout << "Copied vector: ";for (const auto& val : vec2) {std::cout << val << " ";}std::cout << std::endl;Vector<int> vec3 = std::move(vec);std::cout << "Moved vector: ";for (const auto& val : vec3) {std::cout << val << " ";}std::cout << std::endl;std::cout << "Original vector size after move: " << vec.size() << std::endl;return 0;
}