为啥当作为值返回时,类内部的结构定义需要范围解析?

Posted

技术标签:

【中文标题】为啥当作为值返回时,类内部的结构定义需要范围解析?【英文标题】:Why scope resolution necessary for struct define inside a class when returning as value?为什么当作为值返回时,类内部的结构定义需要范围解析? 【发布时间】:2013-06-01 23:35:57 【问题描述】:

我有一个如下所示的单链表实现:

标题

class SinglyLinkedList

  struct Node
  
    Node * _pNext;
    int    _data;
  ;

public:

  Node * SomeFun(Node * ip1, Node * ip2);  
  // Some more methods here
;

现在在实现这个类的方法之一时

CPP

Node * SinglyLinkedList::SomeFun(Node * ip1, Node * ip2)

  //Some code and return

我不理解的奇怪行为是编译时,编译器 拒绝识别返回类型中的“节点”类型,除非我将其指定为 SinglyLinkedList::Node。但是函数参数的相同类型被识别 没有明确指定。理想情况下,我觉得在这两种情况下都应该有 无需显式指定,因为 Node 是在同一个类中定义的。 任何人都可以对此有所了解吗?

【问题讨论】:

好吧,不幸的是,解释是“这是规则”。由于从技术上讲 SinglyLinkedList:: 表示范围的开始,因此您不能在此之前使用 Node 而不对其进行限定。 Ideally I felt that in both cases there should be no need for this explicit specifying because Node is defined in the same class. - 这不是真的,在类之外可以有一个 Node 结构,Node * SinglyLinkedList::SomeFun 可能只使用那个类而不是内部的。 这是新的 C++11 返回符号的原因之一:auto SinglyLinkedList::SomeFun(...) -> Node* 【参考方案1】:
SinglyLinkedList::Node * SinglyLinkedList::SomeFun

在这里,您不在类范围内。但是在参数子句中,或者在函数中,你是在类范围内,所以你不应该限定 Node 来自类 SinglyLinkedList,因为编译器已经知道了。

n3376 3.3.7/1

以下规则描述了类中声明的名称的范围。

声明的潜在范围延伸到或超过类定义的末尾也包括 倾向于由其成员定义定义的区域,即使成员是按词法定义的 在类之外(这包括静态数据成员定义、嵌套类定义、成员函数 定义(包括成员函数体和声明部分的任何部分) declarator-id 之后的定义,包括参数声明子句和任何默认值 论据

【讨论】:

【参考方案2】:

添加到 ForEveR 的答案中,这个问题在 C++11 中使用尾随返回子句解决。

// Regular return style
SinglyLinkedList::Node* SinglyLinkedList::SomeFun(Node * ip1, Node * ip2)  ... 

// Trailing return style
auto SinglyLinkedList::SomeFun(Node * ip1, Node * ip2) -> Node *  ... 

在常规样式中,您尚未进入类范围(它仅在方法的限定名称结束后才开始)。

然而,在尾随返回样式中,返回类型在类范围内(如参数),因此不需要限定。

【讨论】:

以上是关于为啥当作为值返回时,类内部的结构定义需要范围解析?的主要内容,如果未能解决你的问题,请参考以下文章

在Python中,当作为类方法定义中的默认值传递时,赋值运算符是否会访问类或实例变量?

为啥即使从类内部获取成员函数指针值也需要类名限定?

浅谈Java中的内部类

为啥没有通过在 promise 中调用的函数内部的闭包来定义解析?

java并发编程CountDownLatch类源码解析

我在哪里定义内部结构静态对象?看来我不能