“Type of expression” 在 C++ 中是什么?

huangapple go评论94阅读模式
英文:

What is "type of expression" in C++?

问题

我明白什么是"表达式的类别",但我对"表达式的类型"感到困惑。

根据www.cppreference.com

表达式的评估可能会产生一个结果。

那么,结果的类型就是"表达式的类型"吗?

但是,同样根据www.cppreference.com,它说:

每个C++表达式都有两个独立的属性:一种类型和一个值类别。

那么,"类型"是指表达式的类型,还是表达式的结果的类型?

我认为这可能需要一些编译原理的知识(我对此一无所知),最终是表达式的类型首先确定,然后根据它确定表达式结果的类型?还是表达式的结果的类型就是表达式的类型?

请从编译原理的角度给出一个易于理解的解释。

英文:

I know what "category of expression" is, but I'm confused with "type of expression".

According to www.cppreference.com:

> Expression evaluation may produce a result.

So, is the type of the result the "type of expression"?

But, also according to www.cppreference.com:, it says:

> Each C++ expression is characterized by two independent properties: A type and a value category.

So, is "type" refering to the type of the expression, or the type of the result of the expression?

I think this may require some knowledge of compilation principles (I don't know anything about it), in the end is the type of the expression first, and then determine the type of the expression result based on it? Or is the type of the result of the expression the type of the expression?

Please give an easy-to-understand explanation from the perspective of compilation principles.

答案1

得分: 4

每个C++表达式都具有两个独立的属性:类型和值类别。

是的。这里的“类型”指的是表达式的类型。

所以,结果的类型是“表达式的类型”吗?

不一定。表达式和表达式的结果是两个不同的事物。在某些情况下,表达式及其结果的类型相同,而在其他情况下,这些类型是不同的。此外,有些表达式没有任何结果。


表达式的结果在标准中定义如下:

一个glvalue的结果是由表达式表示的实体。
一个prvalue的结果是表达式存储在其上下文中的值;具有cv void类型的prvalue没有结果。
其结果是值V的prvalue有时被称为具有或命名值V的prvalue。
一个prvalue的结果对象是由prvalue初始化的对象;用于计算内置操作符的操作数值或具有cv void类型的prvalue的非丢弃prvalue没有结果对象。


每种表达式的类型都有相应的定义。例如:

一元*操作符执行间接引用。
其操作数必须是类型为“指向T”的prvalue,其中T是对象或函数类型。
该运算符产生了类型为T的lvalue,表示操作数所指向的对象或函数。

突出显示的部分表示表达式的类别是lvalue,表达式的类型是T

例如:

int i = 0;
int* p = &i;
int j = *p;

根据引用的规则,表达式*p的类型是int。它是一个lvalue,结果是对象,也被变量i命名,其类型也是int

此外,[expr.type]部分规定了可能调整任何类型的表达式的类型的规则。

英文:

> > Each C++ expression is characterized by two independent properties: A type and a value category.
>
> So, is "type" refering to the type of the expression

Yes. "type" does refer to the type of the expression there.

> So, is the type of the result the "type of expression"?

Not necessarily. The expression, and the result of the expression are separate things. In some cases the expression and its result do have the same type, while in the other cases those types are different. Furthermore, some expressions don't have any result.


Result of an expression is defined in the standard as such:

> [basic.lval]
>
> The result of a glvalue is the entity denoted by the expression.
The result of a prvalue is the value that the expression stores into its context; a prvalue that has type cv void has no result.
A prvalue whose result is the value V is sometimes said to have or name the value V.
The result object of a prvalue is the object initialized by the prvalue; a non-discarded prvalue that is used to compute the value of an operand of a built-in operator or a prvalue that has type cv void has no result object.


The type of an expression is defined for each kind of expression. For example:

>[expr.unary.op]
>
> The unary * operator performs indirection.
Its operand shall be a prvalue of type “pointer to T”, where T is an object or function type.
The operator yields an lvalue of type T denoting the object or function to which the operand points.

The highlighted part means that the category of the expression is lvalue, and the type of the expression is T.

For example:

int  i = 0;
int* p = &i;
int  j = *p;

The type of the expression *p is int as per the quoted rule. It is an lvalue, and the result is the object - that is also named by the variable i - whose type is also int.

Furthermore, the section [expr.type] specifies rules that may adjust the type of any kind of expression.

答案2

得分: -1

一个完整的标准部分解释了类型是什么。因为有多个类型的类别。例如,函数(而不是函数指针)也是一种类型。它不是尼克劳斯·维尔特(Niklaus Wirth)定义中的“数据类型”。

表达式的类型定义了表达式可能具有的属性,并且在特定上下文中使用时是否可以转换为其他内容,以及与值类别结合使用时是否合法。

例如,void 是一种类型。具有这种类型的表达式不能用作任何值。但是当您调用返回 void 的函数时,调用本身是一个类型为 void 的表达式。

与此相反,void* 是一种指针类型,可以用作值,但不能被解引用或参与算术运算。因为这两种情况都需要对类型为 void 的表达式进行非法使用,作为 gvalue 或 sizeof 的参数。

在英语中,“表达式的类型”和“表达式结果的类型”是同义词。 “表达式的结果”通常是涉及将某些表达式转换为其他内容的上下文语义的不当称呼。有时,这甚至是英语文本有限地翻译到其他语言后的结果,例如当“result”或“cast”无法直接翻译时(我的母语也有这个问题,我们通过从英语中借用其单词来解决这个问题)。

英文:

A whole section of standard explains what type is. Because there are multiple cathegories of types. E.g. a function (not a pointer to a function) is a type too. It's not a "data type" in sense of Niklaus Wirth's definition.

Type of expression defines what properties expression may have and is it convertible to something else when used in certain context and, if combined with value cathegory, if such use is legal.

E.g. void is a type. An expression having such type cannot be used as a value, for anything. But when you call a function which returns void, the call itself an expression of type void.

Contrary to that a void* is a type of pointer which can be used as a value but cannot be dereferenced or be involved in arithmetics. Because both would requre illegal uses an expression of type void, as a gvalue or as argument of sizeof.

In English a "type of expression" and a "type of expression's result" are synonymical. "Result of expression" is often a misnomer of contextual semantics involving certain expressions being cast to something else. Sometimes it's even a result of limited translation of English text to other languages and back, e.g. when "result" or "cast" do not translate directly (my native language got this issue, we come around by robbing English of its words).

huangapple
  • 本文由 发表于 2023年8月10日 09:40:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76872148.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定