【发布时间】:2022-02-18 05:42:38
【问题描述】:
我观察到编译器使用以下 2 个 sn-ps 代码的不同行为:
对于第一个,对于我来说,像 int 这样的基本类型似乎一切正常:
void fi1(int& a) {}
void fi2(int&& a) {}
void func1() {
fi1(2+2); // Do not compile: normal since '2+2' is temporary and is not a variable
int a = 5;
fi2(a); // Do not compile: normal since 'a' is an lvalue
}
但我不明白第二个对象类型:
void fs1(string& a) {}
void fs2(string&& a) {}
void func2() {
fs1(string{""}); // Compile: but weird for me since there is no variable to reference !
fs2(string{""}); // Compile: normal since 'string{""}' is temporary and is not a variable
}
在下面的帖子中: Understanding lvalue/rvalue expression vs object type
据解释,左值是您可以获取其地址的时间。当然,string{""} 应该在内存中的某处有一个地址。但对我来说,右值的一个关键点是你不能在之后使用它,这使得“移动语义”成为可能。
当你在fs2 函数中时,参数是一个右值,你可以做任何你想做的事而没有任何副作用。在fs1 中,您希望其他地方的某些变量在您修改它时会产生一些影响。 fs2 只能使用可变参数调用。
为什么使用 int 而不是使用 object ?
【问题讨论】:
-
如果你明白为什么不能将右值传递给
fi1,为什么不能将一个右值传递给fs1? -
如果你引用一个常量,你会解决可能的错误。
-
fs1(string{""});doesn't compile。好吧,MSVC 确实编译它,但它是错误的。如果您通过/std:c++latest,它将停止这样做。 -
我怀疑这个问题是关于臭名昭著的 Microsoft Visual C++ 扩展,它允许非常量引用绑定到临时对象。
-
@HolyBlackCat 试试 MSVC,它具有允许将非常量引用绑定到临时对象的扩展。编辑我看到你有;)
标签: c++ move-semantics