【问题标题】:An issue about pointer type that is expected as the type of an operand of the operator prefix++ (also for postfix ++)关于指针类型的问题,该类型预期为运算符前缀++的操作数类型(也适用于后缀++)
【发布时间】:2021-03-19 08:45:52
【问题描述】:

prefix++ 的操作数类型定义如下:

操作数的类型应为除 cv bool 以外的算术类型,或指向完全定义的对象类型的指针

措辞object type的正式定义定义为: basic.types#general-8

对象类型是(可能是 cv 限定的)类型,它不是函数类型不是引用类型,并且不是 cv void强>。

但是,请考虑以下代码:

#include <iostream>
struct Test{
  int a;
};
int main(){
 int Test::* member_ptr = &Test::a;
 ++member_ptr;  // Permite this operation?
}

根据object type的定义,member type不被它排除。这是否意味着我们可以将member type 视为object type?你会说members不是对象,所以pointer to member不能作为prefix++的操作数。但是,我会在这里争论,函数是对象吗?这绝对不是,为什么function typeobject typereference type 的定义排除在外。那么,没有将member type放到专属集合中是不是缺陷呢?

更新

MM 的回答引用了这个规则:

除了指向静态成员的指针外,引用“指针”的文本不适用于指向成员的指针。

我知道这条规则。但是,我认为pointers 只是指文字pointers。毕竟pointers这个文字已经出现在标准中了。如:expr.eq#2比较指针定义如下。 (这里绝对可以应用该规则,即不适用于指向成员的指针)。但是,我不认为文本 pointers 也表示 pointer to X 形式(其中 X 不是 member,例如 objectfunction)。有必要澄清这个规则吗?

除了描述任何地方,pointer to X(其中 X 可能是对象、函数或类型)或pointers 不适用于pointer to member

【问题讨论】:

  • 请解释一下member type是什么意思
  • 除非明确提及,“指针”不包括成员指针。
  • @M.M 那可能是class nested-name-specifier of type T。 (但是,不允许将此类内容用作类型说明符)。
  • @PasserBy 是的,我知道that。但是,这里指的是pointer to object type

标签: c++ language-lawyer


【解决方案1】:

[basic.compound]/3:

除了指向静态成员的指针外,引用“指针”的文本不适用于指向成员的指针。

因此,在您引用的第一个文本中,“指向完全定义的对象类型的指针”排除了指向成员的指针的可能性。所以++ 不能应用于指向成员的指针。

【讨论】:

  • 那句话的意思是,pointer to something 不考虑pointer to member,除了文字是明确的pointer to member?我认为这句话的意思是字面意思pointers
  • @jackX 这似乎是您问题中反复出现的主题,要求对英语进行澄清。 “提到“指针”的文本”实际上只是指我们谈论指针的时候。
  • @PasserBy 这就是问题本身。文本pointers 已经出现在标准中,例如“比较指针定义如下”。我以为pointers只是指这样的外观。我不认为文本pointers 也表示pointer to X 形式(其中X 不是成员)。
  • @jackX 除了指向静态成员的指针,任何时候你看到的pointer 通常都不是指向成员的指针。文本指向完全定义的对象类型的指针 不包含指向成员的指针,因为它没有明确提及它们。清除?我真的不明白有什么大不了的。短语pointer to something 显然是指pointer,对吧? “对某事”只是一个额外的限定条件,这里的意思是,除非字面说明,否则不能将限定条件理解为包含非静态成员指针。
  • @jackX 另一种思考方式是:每当你看到 pointerpointer to something 时,无论你认为它是什么,它永远不是非静态成员,除非它是字面意思“指向非静态成员函数的指针”。
【解决方案2】:

每当我的孩子无法理解复杂的数学表达式时,我都会告诉他们:好的,你知道这个表达式全是关于数字的。所以试着用一些数字代替某些子表达式,看看这是否更容易对其进行操作。一旦您对5 代替sin(x)5/10 代替tan(x) 感到满意,然后切换回来。当更好的解释选项用完时,我在这方面取得了相当大的成功。 (我想不出我们使用过的公式的任何实际示例 - 抱歉,我会在稍后(可能是几个月或几年后)想到某些事情时编辑这个问题。

所以,让我们用 C++ 标准来做这件事。每[basic.compound]/3

除了蓝色斑点鸡蛋外,提及“鸡蛋”的文字不适用于蓝色鸡蛋。

然后你引用:

操作数的类型应该是除cv bool以外的算术类型,或者彩蛋。

那个蛋不可能是蓝色的,除非它被字面上说适用于蓝色蛋。

但是,我不认为eggs这个文本也表示颜色X的形式egg。

嗯。如果这是关于鸡蛋,你会不这么认为,对吧?家禽畜牧业和 C++ 之间显然存在体面的同态 :)

  • 蛋=指针
  • 蓝蛋 = 指向成员的指针(一般而言)
  • 蓝色斑点蛋 = 指向静态成员的指针
  • 彩蛋 = 指向完全定义的对象类型的指针
  • 普通(无色鸡蛋 = 指向未完全定义的对象类型的指针

有点像这样:)

有时,确实值得用您熟悉的对象的同态类来代替(我假设您对鸡蛋很熟悉,如果不是 - 铅笔也很好用)。事情听起来并不那么奇怪,我完全理解很难将 C++ 标准视为与某些熟悉的对象有关。假装你熟悉它们并继续前进。

【讨论】:

  • 我知道你的意思。在该规则中造成误解的是text referring to “pointers” 的措辞。当我们看到标准中的文本指针时,措辞似乎是说,只考虑指向成员的指针以外的任何东西。换句话说,这里的pointers 是被认为是一个概念(一组指针)还是只是一个文本。我在这里关心的是text pointers的措辞。
  • 例如,当我要求您将这句话的关键字文本animal 替换为X 时:a tiger, a monkey, a lion, and other animals。我是否要求您替换任何动物或只是文字“动物”?这很模糊。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-22
  • 2013-05-04
  • 2017-09-04
  • 2019-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多