在这种情况下如何测试左值或右值
How to test lvalue or rvalue in this case
代码如下:
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]"
func()。K是一个左值和函数。I是一个x值。
你可以看到更多的细节: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;
}
可分配性"不是左值的好测试,因为我们可以有不可变的左值(例如const引用表达式),并且赋值可以是可以对类类型的右值进行的成员函数调用。
您必须参考标准(ISO/IEC 14882:2011)。
5.2.2/10:如果结果类型是左值引用类型或函数类型的右值引用,则函数调用为左值,如果结果类型是对象类型的右值引用,则函数调用为xvalue,否则为右值。
所以func()
是右值
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
&",E2
的类型为";cq2 vq2T
&",则表达式指定第一个表达式指定的对象的命名成员。如果E1
为左值,则E1.E2
为左值;如果E1
为xvalue,则E1.E2
为xvalue;否则,它是一个右值。[…]
所以func().i
是prvalue
实际上不需要"测试"给定的值是左值还是右值。
从词源学/历史上看,左值是赋值操作符左侧的内容,右值是赋值操作符右侧的内容。(不过这个定义并不完全正确。)注意,右值可以是左值。
简单的经验法则:如果你能获取它的地址,它就是一个左值。然而,在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)
我不确定你到底想要实现什么,但是当你在函数()返回该对象的范围内分配内存时。一旦调用function()返回,这个对象就会超出作用域,因此编译器可以释放它。在后期阶段你可能会遇到很多麻烦。我认为你需要重新设计问题的解决方案。
相关文章:
- 我是c ++的新手,你能解释一下在这种情况下的指针吗
- 在这种情况下,java对象是否可以调用本机函数
- 在这种情况下显式调用时,std::cout 如何更改析构函数的行为?
- 在这种情况下,我真的复制了字节还是复制了字符?
- 为什么在这种情况下,bool 类型的输出等于 0?
- 在这种情况下,如何传递成员函数而不是函数?
- 为什么在这种情况下递增阵列名称有效?
- 在这种情况下我应该使用哪种设计模式
- 为什么在这种情况下我需要 .template
- 在这种情况下,使用 string_view 是否会导致不必要的字符串复制?
- 我是否访问了已释放的内存,或者在这种情况下DrMemory报告不正确?
- 在这种情况下,"typename..."意味着什么?
- 为什么在这种情况下 x = 44?
- 在这种情况下是私有的吗?试图使操作员<<过载
- 在这种情况下,如何防止C++输出/控制台窗体关闭
- 为什么 lambda nullptr 取消引用在这种情况下有效?
- 为什么在这种情况下,前向声明不起作用?
- 为什么在这种情况下不调用我的虚拟函数实现?
- 在这种情况下,为什么模板即时深度超过限制?
- 在这种情况下如何测试左值或右值