C ++中值类别定义中“身份”的含义是什么?

问题描述 投票:6回答:3

简而言之,您可以回答有关身份的部分,谢谢。我对这个问题的主要关注点是从2开始。关于身份,我只是试图提供我当前理解的背景/背景,这样可以帮助你在写答案时决定深度。


我想了解C ++中类型系统和值类别的大图。我在网上搜索/阅读了很多问题和资源,但是每个人都有一个明确的解释,所以我真的很困惑。我会列出我无法掌握的部分,如果有人能提出想法的话

  1. cppreference.com, first line: 对象,引用,函数(包括函数模板特化)和表达式都有一个名为type的属性,它既限制了这些实体所允许的操作,又为其他通用的位序列提供了语义含义。 我的问题: 表达式有什么意思?它是评估后最终结果的类型吗? 我不想在现阶段学习模板,这会妨碍学习基本部分(从你专家的角度来看)吗?我花了一些时间才意识到转发引用和右值引用是不同的东西,前者用于模板。
  2. 价值类别: 我读了这个answer of - What are rvalues, lvalues, xvalues, glvalues, and prvalues?,这句话困扰我很多是身份,这也出现在cppreference.com - Value categories (Line 5, glvalue)。 我的问题:我可以说identity ==我能为它分配一个新值吗? 我看到有人使用word / pointer这个词,但那是has identity iff has address/pointer吗?我想要精确的术语。 我在阅读cppreference.com时遇到了bit-field的想法,似乎给出了一个位字段结构a,它的位字段a.m没有地址?这是使用单词标识而不是地址/指针的原因吗? 我找到了a blog post explaining this,但它的左值定义是反直觉的:左值表示一个资源无法重用的对象,为什么不呢?
c++ language-lawyer lvalue static-typing
3个回答
2
投票
  1. 表达式的类型是其结果将在何时以及何时计算表达式时的类型。不必计算表达式,但所有表达式都具有类型。 Type是静态属性。
  2. 没有关于身份的准确定义,或者指示哪些实体具有或不具有身份。这是一个泥泞的概念,最好不要单独留下。忽略它。有人说对象身份是它的地址,但是这个概念毫无用处。为什么不直接谈谈它的地址呢?比特字段怎么样?他们是没有地址的对象,难道他们没有身份吗?其他人说左撇子有身份而右撇子没有,但那时它就是多余的。

4
投票

identity是一个哲学概念。这是一件让它独一无二的东西。没有两个“东西”可以具有相同的身份。

具有身份的东西是一个实体。

[basic.lval]

glvalue是一种表达式,其评估决定了对象,位域或函数的身份。

表达式中的名称只能指定一个对象。所以表达式中的名称是一个标识。它被定义为左值(例如参见expr.prim.id.unqual

在给定的地址和给定的时间,不能有2个相同类型的对象(可以有彼此嵌套的对象,......)。因此,取消引用指针会给出左值。

引用始终指定实体。因此,在调用时返回引用的每个函数都会生成一个glvalue。

...

xvalue是一个标记,只能由强制转换(或绑定到临时实现)生成。它是一个glvalue,表示一个对象或位字段,其资源可以重用basic.lval

xvalue和左值之间的差异用于生成有效的代码。但是作为左值的xvalue是glvalue:它们带来了实体的身份。

...

prvalue是与任何对象无关的表达式的结果。这是对具有非引用返回类型的函数的调用或某些内置操作符调用的结果的结果。在c ++中,表达式不是实体,因此它没有标识。

prvalues可能有一个结果对象,它可以是一个临时对象。临时是一个实体,它在需要时实现(当一个人尝试获取它或者丢弃一个prvalue时)。


表达式的类型在[expr.type]中明确定义:

如果表达式最初具有“对T的引用”类型([dcl.ref],[dcl.init.ref]),则在进行任何进一步分析之前将类型调整为T.表达式指定由引用表示的对象或函数,表达式是左值或x值,具体取决于表达式。 [注意:在引用的生命周期开始之前或结束之后,行为未定义(请参阅[basic.life])。 - 结束说明]

如果prvalue最初具有类型“cv T”,其中T是cv非限定的非类非数组类型,则在进行任何进一步分析之前将表达式的类型调整为T.

表达式不能具有引用类型。


1
投票

首先,如果你真的想学习C ++的形式/细节,你应该参考标准(或它们的草稿);而不是维基页面(可能是也可能不正确;虽然cppreference通常非常好)。见Where do I find the current C or C++ standard documents?

话虽如此,没有必要研究使用该语言的C ++标准。实际上,大多数开发人员都没有,当然,他们并不打算学习C ++。它们是正式文件,而不是教学/学习材料。所以,如果你只是学习C ++,那就买一本关于它的好书。请参阅The Definitive C++ Book Guide and List


表达式有什么意思?它是评估后最终结果的类型吗?

不,不需要评估(即在运行时)具有类型。例如,sizeof expr的类型为std::size_t,但expr未被评估。

我不想在现阶段学习模板,这会妨碍学习基本部分(从你专家的角度来看)吗?我花了一些时间才意识到转发引用和右值引用是不同的东西,前者用于模板。

实际上,它是相反的,如果你想学习实际用途的C ++,你肯定需要至少学习关于模板的基础知识(如果只使用标准库而不是完全丢失)。

但是,您无需正式了解有关它们如何处理值类型,右值引用或模板本身以便能够编程的所有内容。

这句话困扰我很多是身份

标准中没有“身份”的定义。在C ++ 17中,它在一些地方使用,比如定义glvalue时:

- glvalue是一种表达式,其评估决定了对象,位域或函数的身份。

但是,实际上,你可以说“拥有身份”意味着“实际存在于内存中的某个地方(如果需要)”。你能理解这个术语的最好方法是阅读what Stroustrup wrote

“具有身份” - 即地址,指针,用户可以确定两个副本是否相同,等等。

你也可以用相反的方式思考它:glvalue(具有同一性的东西)是任何不是prvalue的表达式,如果有帮助的话。

© www.soinside.com 2019 - 2024. All rights reserved.