I'm currently learning c++ and is wondering about the which one is the right way to use std::move
//Code might be incorrect since I havent tested it out
Xyt::ByteArray* Xyt::ResourceManager::LoadFileToByteArray(std::string Path)
{
try {
std::ifstream FileStream(Path, std::ios::in);
std::ifstream::pos_type Pos = FileStream.tellg();
FileStream.seekg(0, std::ios::beg);
std::vector<char> Buff(Pos);
FileStream.read(Buff.data(), Pos);
FileStream.close();
//I want to trigger the move constructor here
return new Xyt::ByteArray(std::move(Buff));
}
catch (std::exception e) {
std::cout << "ERROR::FILE::FILE_NOT_SUCCESFULLY_READ" << Path << std::endl;
return nullptr;
}
}
What I'm confused about is which one will trigger the move constructor for std::vector ?
Is it this one (compile error when caller doesnt use std::move)
Xyt::ByteArray::ByteArray(std::vector<char>&& Buffer)
{
this->Buffer = Buffer;
}
this one (accepts both std::move(Buff) and Buff) ?
Xyt::ByteArray::ByteArray(std::vector<char> Buffer)
{
this->Buffer = Buffer;
}
or this one ?
Xyt::ByteArray::ByteArray(std::vector<char> Buffer)
{
this->Buffer = std::move(Buffer);
}
My understanding from reading around the internet, that the 1st constructor is the correct way to utilize the move semantics. But if I use the 1st constructor does that mean I need to make another constructor if I want to actually do a copy on the std::vector Buff ?
Any help would be appreciated!
The only one that works is the third. But that's because you used std::move inside the constructor. And it provokes two moves: one to fill in the parameter, and one from the parameter into the value.
The correct way to do this is:
Xyt::ByteArray::ByteArray(std::vector<char>&& Buf)
: Buffer(std::move(Buf))
{}
This only invokes the move operation once.
You have to explicitly move from named rvalue references if you want to invoke a move operation.
But if I use the 1st constructor does that mean I need to make another constructor if I want to actually do a copy on the std::vector Buff ?
You don't strictly have to. You could require users to do the copying themselves when they call the function:
Xyt::ByteArray(std::vector<char>(Buff))
But yes, if you want users to provide an lvalue directly, and you want to copy from the lvalue, then you need to provide a constructor that takes a (const) lvalue reference and performs a copy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With