代码如下:
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]"
答案 0 :(得分:3)
func()。k是一个左值和func()。我是一个xvalue。
您可以看到以下内容以获取更多详情: rvalues and temporary objects in the FCD
通过,不难测试它们是左值还是左值:
#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;
}
答案 1 :(得分:2)
无需实际“测试”给定值是左值还是左值。
词源/历史上,左值是分配运算符左侧的值,右值是左值。 (但这个定义并不完全正确。)请注意,rvalues可以是左值。
简单的经验法则:如果你可以获取它的地址,那就是左值。但是,在C ++ 11中有rvalue引用,这使得 简单。因此规则更像是:如果您可以使用&
来获取其地址。
也许一些例子可以解决问题:
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)
有关详情,请参阅http://en.wikipedia.org/wiki/Value_%28computer_science%29。
答案 2 :(得分:2)
“可分配性”不是对左值的良好测试,因为我们可以有不可变的左值(例如const引用表达式),并且赋值可以是成员函数调用可以在类类型的 rvalue 上进行。
您必须参考标准(ISO / IEC 14882:2011)。
5.2.2 / 10:如果结果类型是左值引用类型或对函数类型的右值引用,则函数调用是左值,如果结果类型是对象类型的右值引用,则为xvalue,否则为prvalue
因此func()
是 prvalue 。
5.2.5 / 4:如果声明
E2
的类型为“T
的引用”,则E1.E2
为左值;E1.E2
的类型为T
。否则,将适用以下规则之一。
- 如果
E2
是静态数据成员且E2
的类型为T
,则E1.E2
是左值;表达式指定类的命名成员。E1.E2
的类型是T`。
所以func().k
是左值。
- 如果
E2
是非静态数据成员且E1
的类型为“ cq1 vq1X
”,则类型为{{1是“ cq2 vq2E2
”,表达式指定由第一个表达式指定的对象的命名成员。如果T
是左值,则E1
是左值;如果E1.E2
是xvalue,则E1
是xvalue;否则,它是一个prvalue。 [...]
因此E1.E2
是 prvalue 。
答案 3 :(得分:0)
我不确定你究竟想要实现什么,但是当你在function()范围内分配内存时返回该对象。一旦调用function()返回,该对象就超出了范围,因此编译器可以释放它。你可以在以后的阶段遇到很多麻烦。我认为你需要重新设计问题解决方案。