【问题标题】:Type aliasing and self-referencing类型别名和自引用
【发布时间】:2017-04-28 21:38:16
【问题描述】:

例如,单链表节点可能定义如下

namespace example_part1
{
    class node
    {
        node * next;
        int value;
    }
}

假设我们只有一个整数列表。这个类允许有一个指向它自己类型的成员,因为指针都具有相同的大小,而不管底层数据结构的大小。

现在,为什么我不允许这样做

namespace example_part2
{
    using node = std::pair<example_part2::node *, int>;
}

?

我知道这似乎是一个愚蠢的例子,但我想更多地了解它无法编译的原因。我实际上有与此类似的情况,它可能有用(不适用于 std::pair)。另外,假设这两个代码段来自不同的程序,即我没有节点自定义类以及在同一程序中别名为节点的对。

【问题讨论】:

  • node 会同时是一个自定义类和 std::pair 吗?
  • @MillieSmith 请查看我对主要问题的编辑(补充)
  • 那么根据您的编辑,using node = std::pair&lt;node *, int&gt;; 是完全孤独的吗?如,node 尚未定义?它应该如何知道实际类型?递归什么时候结束?
  • @MillieSmith 与它知道类的实际类型的方式相同吗?
  • 当你使用带指针的类时递归结束。您可以使用空指针构造一个节点。你如何构造 std::pair? std::pair&lt;std::pair&lt;std::pair&lt;....., int&gt; *, int&gt; *, int&gt;

标签: c++ self-reference type-alias


【解决方案1】:

在引用type alias declarations at cppreference的规范时,type-id不能直接或间接引用引入的名称:

使用标识符 attr(optional) = type-id ; identifier - 此声明引入的名称,它成为类型名称 template-parameter-list - 模板参数列表,如模板 声明类型 ID - 抽象声明符或任何其他有效的类型 ID (这可能会引入一种新类型,如 type-id 中所述)。 类型标识 不能直接或间接引用标识符。注意点 标识符的声明在后面的分号处 类型 ID。

关于命名空间,请注意std::pair&lt;node *, int&gt; 中的node 不引用命名空间example_part1 的node,因此仍然是未定义的类型名称。

【讨论】:

  • 否决票的任何原因有助于我改进答案?
  • 你完全误解了这个问题。我在上一段中确实说过这两个代码段是完全独立的,就好像它们来自不同的程序一样。然后我更改了代码,使它们位于不同的命名空间中,如 cmets 中所建议的,以进一步澄清。无论如何,感谢您在我的编辑中发现错误。
  • 我猜这是因为他可能希望 pair 中的 node * 创建指向他正在创建的 alias 的指针,而不是指向 @987654328 的指针@ 在另一个命名空间中。
  • 它没有回答他提出的问题。
  • @StephanLechner 最终答案很好,但是在您将其更改为当前版本之前,另一个人首先得到了它(在原始问题的 cmets 部分中)。因此接受了另一个答案
【解决方案2】:

注意type-alias

[type-id is an] 抽象声明符或任何其他有效的 type-id(可能引入 新类型,如 type-id 中所述)。 type-id 不能直接或 间接引用标识符。

本质上,别名可能不是递归的。

【讨论】:

  • (显然,我应该只是在开头发布一个答案,而不是对答案进行评论。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-12
相关资源
最近更新 更多