当我传递文本时,以下代码中的LVALUE和RVALUE在实践上有什么区别? 我的意思是,在这种特殊的字符串情况下(其中字符串是字符串文字),使用RVALUE(&&)有什么好处吗?
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
@NgModule({
...
imports: [
NgbModule,
]
})
export class SurveysModule {}
答案 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);
}
但是可变的右值引用可以绑定到右值,如上所示。