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 toT
,”则E1.E2
为左值;E1.E2
的类型为T
。否则,以下规则之一适用
- 如果
E2
是静态数据成员,并且E2
的类型是T
,则E1.E2
是左值;表达式指定类的命名成员。E1.E2
的类型是T`
所以func().k
是一个左值
- 如果
E2
是非静态数据成员,E1
的类型是“cq1 vq1X
”,而E2
的类型是“cq2 vq2T
”,表达式指定由第一个表达式指定的对象的命名成员。如果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值?)