我有一个类K
,我正在调用函数test
中构建一个对象。所以我相信构造的K
被称为 r-value 。 (这是真的吗?)
但我很困惑,并且担心K
对象显然是 const ,而不是 mutable 。我不想要它。
#include <iostream>
class K {};
std::string test (K &k) {return "mutable";}
std::string test (const K &k) {return "const";}
int main (int argc, const char **argv) {
std::cerr << "K constructed for function argument is " << test(K{}) << "\n";
K k;
std::cerr << "K constructed for local variable is " << test(k) << "\n";
}
为函数参数构造的K是const
为局部变量构造的K是可变的
请注意,当我动态创建K
作为函数参数传递时,我得到一个const对象,而当我创建它作为局部变量时,我得到一个可变的。
出于我的目的,我真的希望两种情况都有可变性。你能告诉我怎么做,或者说服我为什么不应该这样做?
答案 0 :(得分:3)
引用无法绑定到临时对象,但const T&
可以绑定。由于选择了K{}
是临时std::string test (const K &k) {return "const";}
。
如果你真的想要修改临时版,那么可以使用和r值引用
std::string test (K &&k) {return "r-value";}
答案 1 :(得分:1)
在标准C ++中,您无法将临时对象绑定到非const引用。但是,您可以将其绑定到右值引用。 MSVC的用户享受将临时绑定到非const引用的“扩展”。
答案 2 :(得分:0)
看起来你的语法在l值引用和r值引用之间混淆了。
K& k
:这是一个非const l值引用。它通常只能绑定到具有名称的变量。此语法暗示(通常)您正在接受k
和修改函数内部,这样k
也是函数的输出。用临时做这件事实际上没有意义,因为临时性将会消失。对于变量(除了深奥的编译器扩展)之外,它才真正有意义。
const K& k
:const引用。这可以绑定到l或r值。这意味着您在函数中使用k
,但(通常)不需要复制它,当然也不会修改它。这是安全的,因为你无法修改临时(因此没有隐含的假设它将在以后使用),并且临时将在函数的生命周期中存在。
K&& k
:这是一个r值参考。它意味着移动语义,即使用k
的函数只接受一个临时值(或一个随std::move
移动的值),它将取得所述临时值的所有权。
在实践中,我个人发现使用r值参考的唯一必要(或者甚至是适当的)是:
你的第一直觉应该是避免函数调用中的r值。
另一方面,如果您实际尝试将临时绑定到非const引用,我认为这个问题/答案可以更好地解释为什么不允许它: How come a non-const reference cannot bind to a temporary object?