利用vector容器的源代码,写了一个vector的成员函数push_back的时候,对左值引用还是右值引用的例子,包含move语义转换和forward完美转发
#include <iostream>
#include <cstddef>
#include <utility>
template <typename T>
class SimpleVector {
private:
T* data;
size_t size_;
size_t capacity_;
public:
// 构造函数
SimpleVector() : data(nullptr), size_(0), capacity_(0) {}
// 拷贝构造函数
SimpleVector(const SimpleVector& other) : size_(other.size_), capacity_(other.capacity_) {
data = new T[capacity_];
for (size_t i = 0; i < size_; ++i) {
data[i] = other.data[i];
}
}
// 移动构造函数
SimpleVector(SimpleVector&& other) noexcept : data(other.data), size_(other.size_), capacity_(other.capacity_) {
other.data = nullptr;
other.size_ = 0;
other.capacity_ = 0;
}
// 拷贝赋值运算符
SimpleVector& operator=(const SimpleVector& other) {
if (this != &other) {
delete[] data;
size_ = other.size_;
capacity_ = other.capacity_;
data = new T[capacity_];
for (size_t i = 0; i < size_; ++i) {
data[i] = other.data[i];
}
}
return *this;
}
// 移动赋值运算符
SimpleVector& operator=(SimpleVector&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
size_ = other.size_;
capacity_ = other.capacity_;
other.data = nullptr;
other.size_ = 0;
other.capacity_ = 0;
}
return *this;
}
// 析构函数
~SimpleVector() {
delete[] data;
}
// 获取当前元素个数
size_t size() const {
return size_;
}
// 获取当前容量
size_t capacity() const {
return capacity_;
}
// 确保有足够的容量
void reserve(size_t new_capacity) {
if (new_capacity > capacity_) {
T* new_data = new T[new_capacity];
for (size_t i = 0; i < size_; ++i) {
new_data[i] = data[i];
}
delete[] data;
data = new_data;
capacity_ = new_capacity;
}
}
// 重载下标运算符
T& operator[](size_t index) {
return data[index];
}
const T& operator[](size_t index) const {
return data[index];
}
// 利用模板和引用折叠处理左右值的push_back方法
template<typename U = T>
void push_back(U&& value) {
if (size_ == capacity_) {
reserve(capacity_ == 0 ? 1 : capacity_ * 2);
}
// 使用std::forward保持value的左值或右值属性
new (data + size_) T(std::forward<U>(value));
++size_;
}
};
int main() {
SimpleVector<int> vec;
int num = 10;
vec.push_back(num); // 传入左值,自动推导U为int&,引用折叠后保持左值特性
vec.push_back(20); // 传入右值,自动推导U为int&&,引用折叠后保持右值特性
std::cout << "Vector size: " << vec.size() << std::endl;
return 0;
}