【问题标题】:Does my Return Type Need to be Defined?我的返回类型是否需要定义?
【发布时间】:2017-06-17 10:18:56
【问题描述】:

Forward declaration 让我们将定义实际类型推迟到实现文件。对于指向前向声明类型的指针或引用,这是允许的。

I have been told那个:

按值返回不需要类型定义。前向声明就足够了

有人可以通过标准的实际引用来确认或否认这一点吗?我的印象是这是不合法的。

【问题讨论】:

  • 你能清楚你认为什么是不合法的吗?比如,你认为一个实际的代码示例是非法的?
  • 这适用于函数声明,而不是定义。不,这不是标准的引用。
  • 也许我应该说“按值返回不需要类型定义当你声明函数时。前向声明就足够了。”定义函数和调用函数时确实需要定义。
  • 顺便说一下,这也适用于参数。您可以在任何编译器中尝试它。我只是很难在标准中找到确切的确认。
  • “前向声明让我们将实际类型的声明推迟到实现文件” 不,它没有。线索就在名字里;您正在那里声明您的类型。

标签: c++ return-value language-lawyer return-type forward-declaration


【解决方案1】:

按值返回不需要类型定义。前向声明就足够了

声明一个按值返回的函数不需要类型定义。格式良好的演示:

struct S;
S foo();
struct S {};
int main() {
    foo();
}
S foo() {
   return {};
}

定义或调用按值返回的函数确实需要类型定义。标准草案[basic.def.odr]

5 如果以要求类类型完整的方式使用类,则翻译单元中需要一个类的确切定义。 [ 示例:... [snip] ... [ 注意:声明和表达式的规则描述了在哪些上下文中需要完整的类类型。 类类型 T 必须是完整的,如果

  • [剪辑]
  • 5.9 返回类型或参数类型为 T 类型的函数被定义 ([basic.def]) 或调用 ([expr.call]),或
  • [剪辑]

由于不受列表中任何规则的禁止,因此隐式允许声明返回类型不完整的函数。

该规则稍后在标准中重新措辞,并通过例外[dcl.fct] 放宽(感谢@cpplearner 指出此规则):

11 类型不应在返回或参数类型中定义。函数定义的参数类型或返回类型在函数定义的上下文中不应是不完整的(可能是 cv 限定的)类类型,除非函数被删除([dcl.fct.def.delete])。


格式错误的演示:

struct S;
S foo() {
    return {};
} // oops
struct S {};

另一个格式错误的演示:

struct S;
S foo();
int main() {
    foo(); // oops
}
struct S {};
S foo() {
    return {};
}

【讨论】:

  • 赞成,因为这似乎正是 OP 正在寻找的标准中的确认。
  • 对。如果您从编译器设计的角度考虑这一点,那是完全有道理的:如果编译器需要知道其大小/对齐方式,则类型必须是完整的。这些在表达式的代码生成以及为函数设置返回结构时确实很重要。但是对于前向声明当然没关系,前向声明不会出现在生成的代码中,只会更新编译器的内部结构。
猜你喜欢
  • 2014-12-23
  • 1970-01-01
  • 1970-01-01
  • 2012-11-06
  • 2014-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-25
相关资源
最近更新 更多