As part of an assignment in Uni I have to implement a partial clone of the stl::vector class. I've managed nearly all the functionality but I am stumped with how to do push_back(T&& c). We're not allowed to implement emplace like STL itself uses. The object used to test the implementation of the push_backs checks which constructors and operators are invoked on it. For this one ONLY the Move Constructor is allowed to be called. Due to the whole corona hoohaa it's extremely difficult to get any help from teacher / other students.
This is what I have so far:
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 is a T*, _vector_size is a size_t.
To help illustrate why I thought in these patterns here is the other 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;
}
I am at a complete loss what to do. I've perused the source material, the book, and google but I suppose I might be too stupid to realize what I do wrong or where to look :P Halp?
I also looked at this: Vector push_back move implementation which looks like my first attempt. It fails the test because the last line invokes the copy assignment operator, causing a failed assert.
Edit:
To clarify. The portion of the test program runs this:
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");
}
Where it is the last assert that fails. I can't get there by only invoking the Move Constructor.