std :: string参数的右值

时间:2019-04-10 18:56:15

标签: c++ c++11 rvalue-reference temporary-objects

当我传递文本时,以下代码中的LVALUE和RVALUE在实践上有什么区别? 我的意思是,在这种特殊的字符串情况下(其中字符串是字符串文字),使用RVALUE(&&)有什么好处吗?

import {NgbModule} from '@ng-bootstrap/ng-bootstrap';


@NgModule({
    ...
    imports: [
        NgbModule,
    ]
})
export class SurveysModule {}

2 个答案:

答案 0 :(得分:4)

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

当您传递字符串文字时,将从字符串文字中构造一个临时std::string。 rvalue变体可以绑定到此,因为您已经传递了一个临时变量,而lvalue变体可以绑定到临时,因为它是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传递给仅接受右值的函数。

使用右值类型可以获得的好处是可以将其移出。有一篇很棒的文章介绍了为什么可以更快地移动here

尽管如评论中所述,使右值const违反了它的目的,因为它不能再移了。

答案 1 :(得分:4)

首先,常量右值引用并不是真正有用的,因为您无法移动它们。变动价值需要可变的参考才能发挥作用。

让我们以您更正的示例为例:

DocumentsThinSerializer()

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

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"});
}

那为什么要完全使用右值引用呢?为什么不使用可变左值引用?

这是因为可变的左值引用无法绑定到临时对象:

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

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