哪个构造函数将触发移动语义



我目前正在学习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 ::移动时编译错误)

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))
{}

这仅调用一次移动操作。

如果要调用移动操作,则必须明确从命名的rvalue参考移动。


但是,如果我使用第一个构造函数,那意味着如果我想在std :: vector buff上实际执行副本,我需要制作另一个构造函数?

您不必严格这样做。您可以要求用户调用函数时自己进行复制:

Xyt::ByteArray(std::vector<char>(Buff))

但是,是的,如果您希望用户直接提供LVALUE,并且要从lvalue复制,则需要提供一个(const)LVALUE参考并执行副本的构造函数。

<。

最新更新