I'm struggling to understand the exact reason the program fails. Regarding the following program:
#include <iostream>
template < class T, size_t SIZE>
class Stack {
T arr[SIZE] = {};
int pos = 0;
public:
Stack & push(const T & t) {
arr[pos ] = t;
return *this;
}
Stack & push(T && t) {
arr[pos ] = std::move(t);
return *this;
}
T pop() {
return std::move(arr[--pos]);
}
};
class Foo {
std::string s;
public:
Foo(const char* s = "@") : s(s) {}
Foo(Foo && foo) : s(std::move(foo.s)) {}
Foo & operator=(Foo && foo) {
s = std::move(foo.s);
return *this;
}
void print() const { std::cout << s << std::endl; }
};
int main() {
Stack<std::string, 5> s1;
s1.push("hi").push(std::string{ "bye" });
std::cout << s1.pop() << std::endl;
Stack<Foo, 5> s3;
Foo f2;
s3.push(f2);
}
The program fails at s3.push(f2); is it because Foo doesn't have a copy ctor or is it because its assignment operator function only handles Foo&& types?
I'm suspecting it's the assignment operator function but I'm not sure it's not because of copy ctor as well.
CodePudding user response:
Because you provided a custom move cosntructor and assignment operator, the compiler no longer generates default copy constructor and assignment operator.
You either need to write those too, or, even better, remove the custom move operations.
The compiler will then generate all 4 for you, and they might be better than your manually written ones (e.g. one problem is that you forgot noexcept on move operations, so standard containers will prefer making copies to moves in some scenarios).
CodePudding user response:
Well, the compiler tells you:
error: use of deleted function ‘Foo& Foo::operator=(const Foo&)’
So you can solve it by adding that function:
Foo& operator=(const Foo& foo) {
s = foo.s;
return *this;
}
CodePudding user response:
There are 2 solutions (I will not point out design issues assuming you are just experimenting).
As a internal data use
vector<T>instead of the array of fixed size and in the push that accepts theconst&move and useemplace_back(nasty and amoral, also it will leave the src in invalid state).Provide copy constructor to
Foo(this is much more easier)
