Reputation: 826
I have the following class :
class Component {
public:
// Constructor
explicit Component(const void* data, size_t size)
: _size(size),
_data(new int[_size]) {
(void)memcpy(_data, data, _size);
}
// Destructor
~Component() {
delete[] _data;
}
// Copy-ctor.
Component(const Component& o)
: _size(o._size),
_data(new uint8_t[_size]) {
(void)memcpy(_data, o._data, _size);
}
// Assignment operator
Component& operator=(const Component& o) {
if (this != &o) {
delete[] _data;
_size = o.getSize();
_data = new uint8_t[_size];
(void)memcpy(_data, o.getData(), _size);
}
return *this;
}
// Move-constructor
Component(Component&& o)
: _size(o._size),
_data(o._data) {
o._data = nullptr;
}
// Move assignment
Component& operator=(Component&& o) {
if (this != &o) {
delete[] _data;
_size = o._size;
_data = o._data;
o._data = nullptr;
}
return *this;
}
private:
size_t _size;
int _data;
};
I would like to test my move-constructor. So I tried to do :
void f(Component&& c) {
Component c2 = c; // Expect to use move-constructor
}
int data[] = { 0, 1 };
Component c{&data[0], sizeof(data)};
f(std::move(c)); // getting a rvalue reference from lvalue reference
But then I saw that it was my copy-constructor that was called and not the move-constructor. Do you have any idea why ?
Upvotes: 1
Views: 1359
Reputation: 283893
In this code
void f(Component&& c)
{
Component c2 = c; // Expect to use move-constructor
}
c
is an lvalue. That's what lets you use it more than one time inside of f
.
The &&
parameter is an indication that the caller will not need the object any longer and you are free to loot it. But now your function is conceptually the owner... subroutines that you call should not loot your object unless you give them permission in turn.
Making c
an rvalue would break many usecases, for example:
void f(string&& s)
{
string inputfilename = s + ".in";
string outputfilename = s + ".out";
// use s in some other ways
}
To give subroutines permission to loot your parameter, you use std::move
.
Upvotes: 3
Reputation: 96
It looks like you need to change f to
void f(Component&& c) {
Component c2 = std::move(c);
}
And call it like:
f(c);
Please see: similar example
NOTE: I haven't tested it, but please see answers to the other thread for an explanation.
Upvotes: 1