【发布时间】:2020-04-07 15:44:27
【问题描述】:
作为 Uni 任务的一部分,我必须实现 stl::vector 类的部分克隆。我已经管理了几乎所有的功能,但我对如何执行 push_back(T&& c) 感到困惑。我们不允许像 STL 本身使用的那样实现 emplace。用于测试 push_backs 实现的对象检查在其上调用了哪些构造函数和运算符。对于这个,只允许调用移动构造函数。由于整个电晕hoohaa,很难从老师/其他学生那里获得任何帮助。
这是我目前所拥有的:
template <typename T>
void Vector<T>::push_back(T&& c)
{
// code that resizes the vector if needed. Checked to make sure it doesn't invoke anything.
T* a = new T(std::move(c)); // Invokes the Move Constructor, which is fine.
auto b = (_vector_data+_vector_size); // Destination
//std::move(); Move invokes MA
//std::swap(b, a); // Doesn't work, swaps but the value of a ends up somewhere else, I use this method in push_back(const T& c) successfully.
//std::copy(); // Copy invokes CA
++_vector_size;
}
_vector_data 是 T*,_vector_size 是 size_t。
为了帮助说明为什么我认为这些模式是另一个 push_back:
template <typename T>
void Vector<T>::push_back(const T& c)
{
// code that resizes the vector if needed.
T* a = new T(c); // Invokes CC.
auto b = (_vector_data+_vector_size); // Destination
std::swap(b, a);
++_vector_size;
}
我完全不知道该怎么办。我仔细阅读了源材料、书籍和谷歌,但我想我可能太愚蠢了,没有意识到我做错了什么或去哪里看:P Halp?
我也看过这个: Vector push_back move implementation 这看起来像是我的第一次尝试。它没有通过测试,因为最后一行调用了复制赋值运算符,导致断言失败。
编辑:
澄清一下。测试程序的部分运行如下:
struct C {
static std::string usedConstr;
void Test() {}
C() {
usedConstr += "DC";
}
C(const C& c) {
usedConstr += "CC";
}
C(C&& c) {
usedConstr += "MC";
}
C& operator=(const C& c) {
usedConstr += "CA";
return *this;
}
C& operator=(C&& c) {
usedConstr += "MA";
return *this;
}
};
std::string C::usedConstr{};
//Test push_back&&
void TestMove() {
Vector<C> a;
C c;
assert(C::usedConstr == "DC");
a.reserve(4);
C::usedConstr = "";
a.push_back(c);
assert(C::usedConstr == "CC");
C::usedConstr = "";
a.push_back(std::move(c));
assert(C::usedConstr == "MC");
}
最后一个失败的断言在哪里。仅调用移动构造函数是无法到达那里的。
【问题讨论】:
-
如果它是一个向量,你应该有一个像缓冲区这样的东西来存储所有元素,所以不会有这样的
T* a = new T(c),只有*b = c或*b = std::move(c) -
从显示的代码中,我怀疑这个“
Vector”是作为指向单个元素的指针数组实现的?无论如何,您的代码中的问题可能不在此处显示的范围内。 -
@fas 这会导致移动分配运算符检查对存储的对象触发,从而导致断言失败。
-
@DrewDormann 其余代码不涉及如何将事物插入到数组中?
-
您可能想看看
std::aligned_storage。该页面甚至给出了如何将其用于类矢量类的示例。