Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 右值总是恒定的吗?_C++ - Fatal编程技术网

C++ 右值总是恒定的吗?

C++ 右值总是恒定的吗?,c++,C++,当inti=5时 int j = i; 计算结果时,此表达式中的rvaluei是否为常数 我问这个问题,因为在我的复制构造函数中,它的参数要求C++中的代码> const ,内置类型的rrv不能是const或unconst。这根本没有道理。但是,类类型可以有常量值和非常量值 右值只是值(不是对象/变量)。你对“非常量值”有什么理解 对于左值/右值术语有一个常见的误解。它们不是指变量,而是指表达式。表达式可以产生左值或右值,并且可以是常量或非常量 特别是,在您的代码中,表达式i位于定义的右侧i

inti=5时

int j = i;
计算结果时,此表达式中的rvalue
i
是否为常数


我问这个问题,因为在我的复制构造函数中,它的参数要求C++中的代码> const

,内置类型的rrv不能是const或unconst。这根本没有道理。但是,类类型可以有常量值和非常量值


右值只是值(不是对象/变量)。你对“非常量值”有什么理解

对于左值/右值术语有一个常见的误解。它们不是指变量,而是指表达式。表达式可以产生左值或右值,并且可以是常量或非常量

特别是,在您的代码中,表达式
i
位于定义的右侧
int j=i
是左值表达式,而不是右值。为了赋值,有一个从左值到右值的转换,然后将其赋值给新声明的变量

连续性是一个正交的概念——在大多数情况下——它关系到你是否能改变你正在处理的对象

int f();
int& g();
const int& h();
const int k();

int main() {
  f();         // non-const rvalue expression
  g();         // non-const lvalue expression
  h();         // const lvalue expression
  k();         // const rvalue expression
  f() = 5;     // error, cannot assign to an rvalue
  g() = 5;     // correct, can modify a non-const lvalue
  h() = 5;     // error, cannot modify a constant lvalue
}
其他示例要求使用用户定义的类型:

struct test {
   void foo() { x = 5; }
   void bar() const;
   int x;
};
test f();
const test g();
int main() {
   f().foo();      // f() is a non-const rvalue, 
                   // but you can call a method on the resulting object
   g().foo();      // g() is a const rvalue, 
                   // you cannot call a mutating member function
   g().bar();      // but you can call a const member function
}

“Requires a
const
”:如果它接受
const a&
,您也可以传递它一些
a&
,因为从非const到const的转换是隐式进行的。您应该添加“您的副本构造函数”的代码,并解释“Requires a
const
”是什么意思。这将有助于回答你的实际疑问,而不是回答一个可能误导的问题。@Armen:我不是@downvoter,但。。。您说“在C++中,内置类型的rof不能是const或unconst”。rValst必须是const或unconst。在OPs示例中,i是右值,是非常量。如果i被声明为
const int i=5当使用为rValm时,rValst是const .@ qbt::错误:C++标准3.1.9状态类rValk可以具有CV限定类型;非类R值始终具有cv非限定类型。R值应始终具有完整类型或空白类型;除了这些类型之外,左值还可以有不完整的类型。@qbert220:另请参见4.1/1-2:“如果T是非类类型,则右值的类型是T的cv非限定版本…左值所指示的对象中包含的值是右值结果”。所以准确地说,
i
不是右值
i
是一个左值表达式,它被转换为右值。结果的右值为5,类型为
int
。当然,将其描述为非常量
int
,会产生误导,因为对于一个非类右值,无论它是常量还是非常量,都没有任何区别。因此Armen将其描述为“两者都不是”。你可以或多或少地将左值-右值转换视为“从内存中加载值”,尽管这更多地说明了编译器和发出的代码的工作方式,而不是标准实际确定的方式。因此,右值是加载
i
的当前值(可能是加载到寄存器中)的结果,它不是
i
本身。@Armen,@Steve-感谢您的解释。我现在明白了-
I
不是右值。计算表达式
i
的结果是右值。嗨,为什么我不能编译第一个示例?谢谢我试图对错误语句进行注释,但仍然无法编译。@user12321:您可能可以编译,但不能链接,因为函数未定义(错误类似于未定义的符号…?)。向每个函数添加一个函数体,如
{static int x=10;return x;}
,注释标记为错误的行,然后重试。(静态<代码>仅用于确保从返回引用的版本返回后变量仍处于活动状态)