所有临时值都是C++;? 过去几年我一直用C++编写代码。但有一个问题我还没有弄清楚。我想问一下,所有的临时变量都是C++,rValue/

所有临时值都是C++;? 过去几年我一直用C++编写代码。但有一个问题我还没有弄清楚。我想问一下,所有的临时变量都是C++,rValue/,c++,rvalue,temporaries,C++,Rvalue,Temporaries,如果没有,有人能给我一个例子,其中代码中产生的临时值是一个左值吗?数组索引操作既是一个临时值又是一个左值,类似于[10]=1的东西就是一个例子;左值是一个临时的计算指针。那么,数组操作符返回一个引用,任何返回引用的函数都可以被认为做同样的事情吗?所有引用都是常量,虽然它们可以是左值,但它们修改它们引用的内容,而不是引用本身。对于*运算符也是如此 *(一个临时指针)=val 我发誓我曾经使用过一些编译器,它会将临时值传递给任何引用过的函数 所以你可以去: int Afunc() { retu

如果没有,有人能给我一个例子,其中代码中产生的临时值是一个左值吗?

数组索引操作既是一个临时值又是一个左值,类似于[10]=1的东西就是一个例子;左值是一个临时的计算指针。

那么,数组操作符返回一个引用,任何返回引用的函数都可以被认为做同样的事情吗?所有引用都是常量,虽然它们可以是左值,但它们修改它们引用的内容,而不是引用本身。对于
*
运算符也是如此

*(一个临时指针)=val

我发誓我曾经使用过一些编译器,它会将临时值传递给任何引用过的函数

所以你可以去:

int Afunc()
{
   return 5;
}

int anotherFunc(int & b)
{
    b = 34;
}


anotherFunc(Afunc());
但是,现在找不到一个允许您这样做的引用,引用必须是const才能允许传递临时值

int anotherFunc(const int & b);
无论如何,引用可以是左值和临时的,诀窍是引用本身不被修改,只修改它引用的内容


如果你将<代码> -> >代码>运算符作为运算符,那么临时指针可以是LValk,但同样的条件也适用,它不是临时指针,它将被改变,而是它指向的事物。

< P>这取决于你认为临时变量是什么。你可以这样写

#include <stdio.h>
int main()
{
    char carray[10];
    char *c=carray+1;
    *(c+2+4) = 9;
    printf("%d\n",carray[7]);
    return 0;
}
#包括
int main()
{
char-carray[10];
char*c=carray+1;
*(c+2+4)=9;
printf(“%d\n”,carray[7]);
返回0;
}
这在VisualStudios和GCC中运行。您可以在中运行代码


我考虑(c++ 2+4)一个rVald,虽然我想给它赋值。当我取消引用它时,它将变成左值。所以是的,所有的临时变量都是右值。但是你可以通过取消对右值的引用,将右值(因此是临时值)变成左值。简短的回答:是的,但我不打算引用这个标准,因为证明这一点需要解决所有临时值。根据定义,临时语句的生命周期只有一条语句,所以将内容分配给一条语句最多也是一种糟糕的样式

有趣的回答:复制省略可以(经常)使临时对象与左值对象相同。比如说,

MyClass blah = MyClass( 3 ); // temporary likely to be optimized out

编辑:关于在这些情况下是否存在任何临时对象的问题,§12.8/15提到

可以通过将临时对象直接构造到被省略副本的目标中来省略复制操作


这表明有一个临时对象可能与左值相同。

Prasoon Saurav已经链接了一个非常好的clc++线程。在那里,詹姆斯·坎兹解释了为什么这个问题没有真正意义。归结起来是:

  • 右值是表达式的一个(布尔)属性-每个表达式要么是左值,要么是右值
  • 临时词语不是表达
因此,这个问题没有意义

下面的代码就是一个很好的示例:

int main() {
  const int& ri = 4;
  std::cout << ri << std::endl; 
}
intmain(){
常数int&ri=4;
标准::coutNo

<> P> C++语言规范从来没有像你所问的那样做出这样直截了当的断言。它没有说语言标准中任何“所有临时对象都是rVals”的地方。此外,问题本身有一点误称,因为C++语言中的rof属性不是对象的属性,而是表达式的属性(即其结果的属性)。。这实际上是语言规范中定义它的方式:对于不同类型的表达式,当结果是左值和右值时,它会显示。除此之外,这实际上意味着临时对象可以作为右值和左值访问,具体取决于用于执行操作的表达式的特定形式入口

例如,literal
2+3
表达式的结果显然是一个右值,一个类型为
int
的临时值。我们不能将一元
&
应用于它,因为一元
&
需要一个左值作为其操作数

&(2 + 3); // ERROR, lvalue required
但是,众所周知,常量引用可以附加到临时对象,如

const int &ri = 2 + 3;
在这种情况下,引用被附加到临时变量上,从而延长了后者的生命周期。显然,一旦完成,我们就可以访问与左值
ri
相同的临时变量,因为引用总是左值。例如,我们可以轻松合法地将一元
&
应用到引用,并获得指向e临时

const int *pi = &ri;
只要临时命令持续存在,指针就保持完全有效

左值访问临时对象的另一个明显例子是,当我们通过其
this
指针访问类类型的临时对象时。
*this
的结果是左值(一元
*
应用于数据指针的结果总是如此)对于给定的类类型
t
,表达式
t()
是一个右值,正如语言标准中明确规定的那样,但是临时对象可以通过
*t()访问
)是左值。与前面的示例不同,此方法允许您立即获取非常量限定左值,该左值引用临时对象

因此,同样的临时对象可能很容易被“视”为右值或左值,这取决于您使用什么类型的表达式(什么类型的访问路径)来“查看”该对象

如果没有,谁能给我一个例子,其中代码中生成的临时值是左值

下面的代码将常量引用绑定到临时对象
const int *pi = &ri;
int i;
const float &cfr = i;
int i;
const float __tmp_cfr = i; // introduced by the compiler
const float &cfr = __tmp_cfr;