Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.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++_Lvalue_Rvalue - Fatal编程技术网

C++ 在这种情况下如何测试左值或右值

C++ 在这种情况下如何测试左值或右值,c++,lvalue,rvalue,C++,Lvalue,Rvalue,代码如下: struct A { static int k;   int i; };   int A::k = 10;   A func() { A a; return a; } 我的问题是,如何判断func().k或func().I是否为左值?如果两者都是左值/右值,如何测试它们 func().k = 0; // compile ok under g++-4.4 and g++-4.6 func().i = 1; // compile ok with g++-4.4, but g++

代码如下:

struct A
{
   static int k;
   int i;
};
 
int A::k = 10;
 
A func() { A a; return a; }
我的问题是,如何判断
func().k
func().I
是否为左值?如果两者都是左值/右值,如何测试它们

func().k = 0; // compile ok under g++-4.4 and g++-4.6
func().i = 1; // compile ok with g++-4.4, but g++-4.4 gives an error: 
              //"using temporary as lvalue [-fpermissive]"

我不确定您到底想要实现什么,但当您在返回该对象的函数()范围内分配内存时。一旦对function()的调用返回,这个对象就会超出范围,因此编译器可以释放它。在以后的阶段你可能会遇到很多麻烦。我认为您需要重新设计问题解决方案。

实际上没有必要“测试”给定值是左值还是右值

从词源学/历史上看,左值是位于赋值运算符左侧的值,右值是位于右侧的值。(这个定义并不完全正确。)注意右值可以是左值

简单的经验法则:如果你能得到它的地址,它就是一个左值。然而,在C++11中,有一些右值引用使得事情变得不那么简单。因此,规则更像是:如果您可以使用
&
获取其地址

也许一些例子可以澄清问题:

int a = 5; // a is an lvalue, 5 is an rvalue
int b = fun(); // fun is an rvalue
fun() = a; // illegal, can't assign to an rvalue (suppose foo returns int)
有关详细信息,请参见。

func().k是左值,func().i是x值

有关更多详细信息,请参见:

尽管如此,测试它们是左值还是右值并不困难:

#include <iostream>

struct A
{
    static int k;
    int i;
};

int A::k = 10;

A func( ){ A a; return a; }

void f (int & ) { std::cout << "int& " << std::endl; }

int main ()
{
    func().k = 0;  //ok, because func().k is an r
    f(func().k);
    func().i = 1; //compile error: "using temporary as lvalue"
    f(func().i);  //compile error because func().i is an rvalue of type ‘int’
    return 0;
}
#包括
结构A
{
静态int k;
int i;
};
int A::k=10;
func(){A;返回A;}
void f(int&{std::cout“可赋值性”不是一个很好的左值测试,因为我们可以有不可变的左值(例如常量引用表达式),赋值可能是一个成员函数调用,可以在类类型的右值上进行

您必须参考该标准(ISO/IEC 14882:2011)

5.2.2/10:如果结果类型是对函数类型的左值引用类型或右值引用,则函数调用为左值;如果结果类型是对对象类型的右值引用,则函数调用为xvalue;否则为prvalue

因此
func()
是一个PR值

5.2.5/4:如果声明
E2
具有类型“reference to
T
,”则
E1.E2
为左值;
E1.E2
的类型为
T
。否则,以下规则之一适用

  • 如果
    E2
    是静态数据成员,并且
    E2
    的类型是
    T
    ,则
    E1.E2
    是左值;表达式指定类的命名成员。
    E1.E2
    的类型是T`
所以
func().k
是一个左值

  • 如果
    E2
    是非静态数据成员,
    E1
    的类型是“cq1 vq1
    X
    ”,而
    E2
    的类型是“cq2 vq2
    T
    ”,表达式指定由第一个表达式指定的对象的命名成员。如果
    E1
    是左值,则
    E1.E2
    是左值;如果
    E1
    是x值,则
    E1.E2
    是x值;否则,它是prvalue。[…]

因此
func().i
是一个PR值。

您不能“测试”它。你只要应用语法规则……如果编译器在你赋值时没有抱怨,它就是一个左值。你想检查变量
k
i
是否是右值吗?@我知道的另一个测试,我只想理解他在问什么。@0x499602D2我在一次采访中遇到了这个问题。很容易看出func().k是一个左值,因为我们可以像
func().k=0
那样给它赋值。但是我不确定
func().I=1
的情况。返回一个副本?不会引起任何问题。这取决于用户以后如何使用它。安全总比抱歉好,对吗?你为什么认为
func().I
是一个xvalue?(
func())
按值返回,所以
func()
是一个PR值,所以
func().i
当然也是一个PR值?)