POD,非POD,右值和左值 [英] PODs, non-PODs, rvalue and lvalues

查看:140
本文介绍了POD,非POD,右值和左值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都可以根据右值,左值,POD和非POD来解释下面标记的第一个表达式是的原因,而下面标记的第二个表达式是否正确?在我的理解,int()和A()应该是右值,没有?

Could anyone explain the details in terms of rvalues, lvalues, PODs, and non-PODs the reason why the first expression marked below is not ok while the second expression marked below is ok? In my understanding both int() and A() should be rvalues, no?


struct A {};

int main()
{
  int i;
  A a;

  int() = i; //Not OK (error).
  A() = a; //OK.

  return 0;
}


推荐答案

你从表达式中获得什么(从C标准中获取的一个有用的简化,但不是C ++标准中的写法)。 Lvalues是定位器值。 Lvalues可以用作右值。引用总是左值,即使是const。

Rvalues are what you get from expressions (a useful simplification taken from the C standard, but not worded in C++ standardese). Lvalues are "locator values". Lvalues can be used as rvalues. References are always lvalues, even if const.

你必须注意的主要区别可以缩小到一个项目:你不能取一个rvalue(再次,不是standardese,但是一个有用的规则的泛化)。或者换句话说,你不能为右值&mdash修正一个精确的位置;如果可以,那么你会有一个左值。 (你可以绑定一个常量和一个右值来修复它在适当位置,并且0x正在彻底改变规则。)

The major difference of which you have to be aware can be condensed to one item: you can't take the address of an rvalue (again, not standardese but a useful generalization of the rules). Or to put it another way, you can't fix a precise location for an rvalue—if you could, then you'd have an lvalue. (You can, however, bind a const& to an rvalue to "fix it in place", and 0x is changing the rules drastically.)

用户定义的类型但是,如果类的接口允许它可以将任何右值转换为左值:

User-defined types (UDTs), however, are slightly special: you can convert any rvalue into an lvalue, if the class's interface allows it:

struct Special {
  Special& get_lvalue() { return *this; }
};
void f() {
  // remember "Special()" is an rvalue
  Special* p = &Special().get_lvalue(); // even though you can't dereference the
  // pointer (because the object is destroyed), you still just took the address
  // of a temporary

  // note that the get_lvalue() method doesn't need to operate on a const
  // object (though that would be fine too, if the return type matched)
}

类似的事情发生在你的 A()= a 提供的赋值运算符,将右值 A()转换为 * this 。引用标准,12.8 / 10:

Something similar is happening for your A() = a, except through the compiler-supplied assignment operator, to turn the rvalue A() into *this. To quote the standard, 12.8/10:


如果类定义没有显式声明一个拷贝赋值运算符,隐式地。类X的隐式声明的拷贝赋值运算符将具有形式

If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. The implicitly-declared copy assignment operator for a class X will have the form

X& X::operator=(const X&)


继续更多的资格和规格,但这是重要的一点。因为这是一个成员函数,它可以在rvalues上调用,就像Special :: get_lvalue可以,就好像你写了 A()。operator =(a) A()= a

And then it goes on with more qualifications and specs, but that's the important bit here. Since that's a member function, it can be called on rvalues, just like Special::get_lvalue can be, as if you had written A().operator=(a) instead of A() = a.

int()= 1 被明确禁止,因为你发现,因为ints没有以相同的方式实现operator =。

The int() = 1 is explicitly forbidden as you discovered, because ints don't have operator= implemented in the same way. However, this slight discrepancy between types doesn't matter in practice (at least not that I've found).

这篇关于POD,非POD,右值和左值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆