【问题标题】:T* and const T*T* 和常量 T*
【发布时间】:2014-01-21 19:13:37
【问题描述】:

我相信这可能适用于许多 T,但我确信这适用于整数。作为学习 C++ 的一部分,我试图用标准中的语言来解释以下行为。

typedef const int * constintptr;
typedef int * intptr;

intptr p;
constintptr cp = p;
const constintptr& crcp = p;
//constintptr & rcp = p;

通过查看 n3337,第 8.5.3 节。似乎这种行为是通过说 int* 可转换为 const int * prvalue 来解释的,但与引用不兼容。 (如果我错了,请纠正我)。

我看到这是可取的行为(或者我们可以颠覆 const),而这种行为的可取性不是这个问题的意义所在。

问题是在标准中指定(或暗示)它们 intptr 和 constintptr 不兼容引用。

【问题讨论】:

  • 我认为这很简单:p 不是constintptr 类型的值。你可以 convert 它,它给出一个临时的,因此是一个右值,但右值不绑定到左值引用。
  • 我相信,唯一与引用兼容的东西是一些常见继承层次结构中的派生类。

标签: c++ pointers c++11 constants


【解决方案1】:

同一部分,8.5.3/4(编号从 n3797 开始,我有)定义了引用兼容:

给定类型“cv1 T1”和“cv2 T2”,“cv1 T1”是参考相关的 如果 T1T2 的类型相同,或者 T1T2 。 “cv1 T1”与“cv2 T2引用兼容如果T1是 与 T2cv1 相关的引用与 cv 限定相同,或 cv-qualification 大于 cv2

所以你的类型 T1 是 int* 和 T2 int const*。它们不是同一类型。它们中的任何一个都不是另一个的基类(因为它们都不是一个类)。因此,它们与引用无关。

当标准说“cv1 T1”时,它表示将constvolatile 中的0 个或多个应用于T1 类型的任何类型。它表示文本替换,也就是说,它不表示由 0 个或多个关键字 constvolatile 后跟另一个标记序列声明的任何类型T1 的类型声明。

因此,您可能误解了这一点,以至于您认为 const int*int* 的 cv 限定版本。如果是,那么根据一般规则,它们将与参考相关,因此标准中需要有文本才能例外。但事实并非如此。 int *constint* 的 cv 限定版本。

【讨论】:

  • 我的问题是,基本上,标准是否提到 int* 和 int const* (或其他类型)除了转换之外没有任何特殊的关系?
  • @orm:您的意思是,标准中是否有单独的部分说,“由于 8.5.3 中的定义,以下类型对与引用无关:”通过包括“const int*int*”在内的完整示例列表。我对此表示怀疑。该标准确实包含示例来说明其规则,但除此之外,说明定义中已经涵盖的特定情况是多余的。
  • 一般来说不是 8.5.3 的结果。这就是我的意思。在您的推理中:“它们不是同一类型。它们都不是另一个的基类。”他们不是彼此的基类的句子,这是从哪里来的。我明白你是多么不想要那样。但这是指定的吗?是因为它们不是类吗?是不是因为除非它说它们是相关的,否则它们不是?
  • @orm:是的,它们不是类类型,因此肯定不是另一个的基础。你也是正确的,如果“相关”的定义没有说它们是相关的,那么它们是不相关的。这就是定义的意思。在描述技术术语时,斜体文本(当我复制并粘贴此引用时想到它丢失了)表示标准中的定义。
  • @SteveJessop:关于“它们不是类类型,因此肯定一个不是另一个的基础”,关于正式术语的假设很少,其中单词并不总是意味着它们听起来喜欢。例如,与“基础”相同,“最派生”可能需要类类型,所以如果它不是类类型肯定不是那样,是吗?然而,在 C++11 §1.8/4 中,人们发现“最派生类类型或非类类型的对象称为最派生对象”。形式上,大多数派生并不意味着任何基类,甚至是类类型......只是说'。
猜你喜欢
  • 2015-06-23
  • 1970-01-01
  • 2012-05-28
  • 1970-01-01
  • 2012-10-02
  • 2016-12-12
  • 1970-01-01
  • 2013-06-24
  • 2017-08-21
相关资源
最近更新 更多