哪个构造函数将触发移动语义?
Which constructor will trigger the move semantics?
我目前正在学习 C++,并且想知道哪一个是正确的使用方法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;
}
}
我感到困惑的是哪个会触发 std::vector 的移动构造函数?
是这个吗(调用者不使用std::move时编译错误)
Xyt::ByteArray::ByteArray(std::vector<char>&& Buffer)
{
this->Buffer = Buffer;
}
这个(同时接受 std::move(Buff) 和 Buff)?
Xyt::ByteArray::ByteArray(std::vector<char> Buffer)
{
this->Buffer = Buffer;
}
还是这个?
Xyt::ByteArray::ByteArray(std::vector<char> Buffer)
{
this->Buffer = std::move(Buffer);
}
根据我在网上阅读的理解,第一个构造函数是利用移动语义的正确方法。但是,如果我使用第一个构造函数是否意味着如果我想在 std::vector Buff 上实际做一个副本,我需要创建另一个构造函数?
如有任何帮助,我们将不胜感激!
唯一有效的是第三个。但那是因为您在 构造函数中使用了 std::move
。并且引发了两招:一是填入参数,一是从参数入值。
正确的做法是:
Xyt::ByteArray::ByteArray(std::vector<char>&& Buf)
: Buffer(std::move(Buf))
{}
这只会调用一次移动操作。
如果要调用移动操作,则必须显式地从命名右值引用中移动。
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 ?
您不一定非得这样做。您可以要求用户在调用函数时自己进行复制:
Xyt::ByteArray(std::vector<char>(Buff))
但是是的,如果你希望用户直接提供一个左值,并且你想从左值复制,那么你需要提供一个构造函数,它接受一个 (const
) 左值引用并执行复制.
我目前正在学习 C++,并且想知道哪一个是正确的使用方法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;
}
}
我感到困惑的是哪个会触发 std::vector 的移动构造函数?
是这个吗(调用者不使用std::move时编译错误)
Xyt::ByteArray::ByteArray(std::vector<char>&& Buffer)
{
this->Buffer = Buffer;
}
这个(同时接受 std::move(Buff) 和 Buff)?
Xyt::ByteArray::ByteArray(std::vector<char> Buffer)
{
this->Buffer = Buffer;
}
还是这个?
Xyt::ByteArray::ByteArray(std::vector<char> Buffer)
{
this->Buffer = std::move(Buffer);
}
根据我在网上阅读的理解,第一个构造函数是利用移动语义的正确方法。但是,如果我使用第一个构造函数是否意味着如果我想在 std::vector Buff 上实际做一个副本,我需要创建另一个构造函数?
如有任何帮助,我们将不胜感激!
唯一有效的是第三个。但那是因为您在 构造函数中使用了 std::move
。并且引发了两招:一是填入参数,一是从参数入值。
正确的做法是:
Xyt::ByteArray::ByteArray(std::vector<char>&& Buf)
: Buffer(std::move(Buf))
{}
这只会调用一次移动操作。
如果要调用移动操作,则必须显式地从命名右值引用中移动。
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 ?
您不一定非得这样做。您可以要求用户在调用函数时自己进行复制:
Xyt::ByteArray(std::vector<char>(Buff))
但是是的,如果你希望用户直接提供一个左值,并且你想从左值复制,那么你需要提供一个构造函数,它接受一个 (const
) 左值引用并执行复制.