std :: string参数的rvalue

问题描述 投票:4回答:2

当我传递文本时,以下代码中LVALUE和RVALUE之间的实践差异是什么?我的意思是,在字符串的这种特定情况下(字符串是字符串文字),使用RVALUE(&&)有什么好处?

void write_Lvalue(const std::string &text) {
    //...
}

void write_Rvalue(const std::string &&text) {
    //...
}

int main() {
    write_Lvalue("writing the Lvalue");
    write_Rvalue("writing the Rvalue");
}
c++ c++11 rvalue-reference temporary-objects
2个回答
4
投票

首先,恒定的右值参考不是很有用,因为你无法移动它们。移动价值需要可变的参考工作。

我们来看看你纠正的例子:

void write_lvalue(std::string const& text) {
    //...
}

void write_rvalue(std::string&& text) {
    //...
}

int main() {
    write_lvalue("writing the Lvalue");
    write_rvalue("writing the Rvalue");
}

在这种情况下,两者完全相同。在这两种情况下,编译器必须创建一个字符串并通过引用发送它:

int main() {
    // equivalent, string created
    // and sent by reference (const& bind to temporaries)
    write_lvalue(std::string{"writing the Lvalue"}); 

    // equivalent, string created
    // and sent by reference (&& bind to temporaries)
    write_rvalue(std::string{"writing the Rvalue"});
}

那么为什么要有rvalue引用的函数呢?

这取决于你对字符串的处理方式。可以从以下位置移动可变引用:

std::string global_string;

void write_lvalue(std::string const& text) {
    // copy, might cause allocation
    global_string = text;
}

void write_rvalue(std::string&& text) {
    // move, no allocation, yay!
    global_string = std::move(text);
}

那么为什么要使用右值参考呢?为什么不使用可变左值参考?

那是因为可变的左值引用不能绑定到临时值:

void write_lvalue_mut(std::string& text) {
    // move, no allocation... yay?
    global_string = std::move(text);
}

int main() {
    std::string s = /* ... */;
    write_lvalue_mut(std::move(s)); // fails
    write_lvalue_mut("some text"); // also fails
}

但是可变rvalue引用可以绑定到rvalue,如上所示。


4
投票

在这种情况下没有任何好处。 write_Rvalue只接受右值。和write_Lvalue只接受左值。

当你传递一个字符串文字时,将从字符串文字构造一个临时的std::string。 rvalue变量已经可以绑定到此,因为您已经传递了一个临时变量,而左值变量可以绑定到临时变量,因为它是const

例如,这将不会编译:

void write_Lvalue(const std::string &text) {
    //...
}

void write_Rvalue(const std::string &&text) {
    //...
}

int main() {
    std::string a = "hello";
    write_Rvalue(a);
}

因为我们试图将左值a传递给只接受右值的函数。

使用rvalue类型可以获得的好处是可以从中移除它们。有一个很好的帖子,为什么移动可以更快here

尽管正如评论中所说,让你的右撇子const失败了它的目的,因为它不能再被移动了。

© www.soinside.com 2019 - 2024. All rights reserved.