我实现的push_back函数:
void push_back(T& num) {
my_vec[index] = num;
index++;
}和emplace_back函数:
template<class... Args>
void emplace_back(Args&&... args) {
push_back(T(std::forward<Args>(args)...));
}你觉得这有什么问题吗?如果是,你能告诉我吗?
另外,请让我知道这是如何工作的?
请注意: emplace_back不是我的实现,我是在寻找实现我自己的emplace_back的方法时从其他问题中获取的。
发布于 2021-06-09 18:55:59
你并不是真的在使用它。还有一项任务。
它使用T数组的大小和对齐来分配原始内存,然后实例化原始内存中的对象。
考虑到这一点,您可能应该用emplace_back来实现push_back,而不是相反。
template <typename T>
class my_vector {
T * start;
std::size_t size;
std::size_t capacity;
void grow(); // Implementation of this is left as an exercise to the reader
public:
template <typename... Args>
reference emplace_back(Args&&... args) {
if (size == capacity) grow();
return *new (start + size++) T(std::forward<Args>(args)...);
}
reference push_back(const T & t) { return emplace_back(t); }
reference push_back(T && t) { return emplace_back(std::move(t)); }
}还有,请让我知道这是如何工作的?
template <typename... Args>允许零个或多个类型匹配此模板,然后T(std::forward<Args>(args)...)使用这些参数构造一个T,"perfectly forwarding",即,右值作为右值传递,左值作为左值传递。
注:因为std::vector不new[],所以您不能实现行为与std::vector 20之前的C++完全相同的东西,因为它必须能够在不构造T数组的情况下从data返回指向T数组的指针。
发布于 2021-06-09 18:50:41
emplace_back的要点是在适当的位置构造一个对象。您的实现构造了一个对象,然后将其复制到my_vec。
您的实现将无法处理不可复制的类型。例如,这将不会编译:
Vector<std::thread> v;
v.emplace_back([](){});
v.push_back(std::thread([](){}));将push_back更改为通过右值引用接受其参数将解决此问题:
void push_back(T&& num) {
my_vec[index] = std::move(num);
index++;
}
template<class... Args>
void emplace_back(Args&&... args) {
push_back(T(std::forward<Args>(args)...));
}然而,我认为大多数标准库实现都是使用emplace_back作为最低层函数来实现的:
void push_back(T&& num) {
emplace_back(std::move(num));
}
template<class... Args>
void emplace_back(Args&&... args) {
my_vec[index] = T(std::forward<Args>(args)...);
index++;
}这使得实现复制值的push_back重载变得更容易:
void push_back(const T& num) {
emplace_back(num);
}注意,这个实现使用了移动赋值,这仍然不是emplace_back的意图,它需要在未初始化的内存上使用位置新构造一个对象,但假设my_vec是一个对象数组或类似的对象,这是您所能做的最好的事情(没有完全实现std::vector的语义,这是相当复杂的)。
https://stackoverflow.com/questions/67900997
复制相似问题