标准措辞在哪里允许在函数声明中使用不完整类型,但在函数定义中要求完整类型?

发布于 2025-01-04 19:08:22 字数 493 浏览 2 评论 0原文

我最近发现非定义函数声明中的参数类型可能是不完整类型。这非常令人兴奋。

class A;
class B {
   B(A a);      // Legal! Wow!
};

仅在定义时才要求类型完整:

B::B(A a) {};   // error: ‘a’ has incomplete type

我一直在尝试为此确定法律术语,但我在 C++11 中搜索“[in]complete type”并没有产生任何有趣的结果,导致我假设这些语义是通过神秘的迷宫结构来定义的。

您能帮我确定定义函数声明与定义中函数参数类型是否完整的上述要求的标准文本吗?

(9.2/109.4.2/2 为我们提供了 static 数据成员声明和非static 类定义中的数据成员定义。)

I recently found out that the types of parameters in a non-defining function declaration may be of incomplete types. This is very exciting.

class A;
class B {
   B(A a);      // Legal! Wow!
};

The type is required to be complete only for the definition:

B::B(A a) {};   // error: ‘a’ has incomplete type

I've been trying to pin down the legalese for this, but my searches through C++11 for "[in]complete type" have yielded nothing of much interest, leading me to assume that these semantics are defined through an enigmatic maze of constructions.

Can you help me pin down the standard text that defines the above requirements for the types of function parameters being complete or otherwise, in function declarations vs definitions?

(9.2/10 and 9.4.2/2 give us the requirements for static data member declarations and non-static data member definitions in class definitions.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

已下线请稍等 2025-01-11 19:08:22

请参阅 8.3.5p9,其中规定了确切的规则。对于 = delete 定义,实现为

特别是,在非定义函数声明中不会对参数或返回值执行任何操作。将参数复制到参数是在调用者的上下文中完成的。参数的销毁是在被调用者的上下文中,在函数定义中完成的。返回值的销毁是在函数调用中的调用者上下文中完成的,除非该调用是decltype中最顶层逗号运算符的最顶层表达式或右操作数。然后不会发生破坏,因为没有创建临时文件作为特殊情况(以帮助 SFINAE 库)。

See 8.3.5p9, which lays down the exact rules. For a = delete definition, implementations are likely to accept incomplete parameter types too, retroactively (as was determined in a DR resolution by the C++ committee).

In particular, there is no action done on parameters or return values in a non-defining function declaration. Copying of arguments to parameters is done in the context of the caller. And destruction of parameters is done in the context of the callee, in the function definition. Destruction of the return value is done in the context of the caller in a function call except if the call is the topmost expression or right operand of a topmost comma operator in a decltype. Then no destruction happens because no temporary is created as a special case (to help SFINAE libraries).

只涨不跌 2025-01-11 19:08:22

函数声明

似乎没有任何东西可以直接解决这个问题。可能是因为它不被禁止,所以才被允许。

7.1.1/9 告诉我们可以使用 extern 声明(语义上类似于成员函数声明),并以非规范方式向我们展示这样的类型声明可能不完整:

[C++11: 7.1.1/9]: 已声明但未定义的类的名称可以在 extern 声明中使用。这样的声明只能以不需要完整类类型的方式使用。 [示例:

<前><代码>结构S;
外部 S a;
外部 S f();
外部无效 g(S);
无效 h() {
g(a); // 错误:S 不完整
f(); // 错误:S 不完整
}

—结束示例]

函数定义(感谢 litb)

[C++11: 8.3.5/9]: 不得在返回或参数类型中定义类型。 函数定义的参数类型或返回类型不得是不完整的类类型(可能是 cv 限定的),除非函数定义嵌套在该类的成员规范中(包括定义)在定义的嵌套类中
类)。

函数调用

[C++11: 5.2.2/4]: [..] 调用函数时,具有对象类型的参数应具有完全定义的对象类型。 [注意:这仍然允许参数是对不完整类类型的指针或引用。但是,它可以防止按值传递的参数具有不完整的类类型。 —尾注] [..]

Function declaration

There doesn't appear to be anything directly addressing this. It may be that it's allowed because it is not disallowed.

7.1.1/9 tells us that it's ok for an extern declaration (which is semantically similar to a member function declaration), and shows us non-normatively that types in such declarations may be incomplete:

[C++11: 7.1.1/9]: The name of a declared but undefined class can be used in an extern declaration. Such a declaration can only be used in ways that do not require a complete class type. [ Example:

struct S;
extern S a;
extern S f();
extern void g(S);
void h() {
  g(a); // error: S is incomplete
  f(); // error: S is incomplete
}

—end example ]

Function definition (thanks litb)

[C++11: 8.3.5/9]: Types shall not be defined in return or parameter types. The type of a parameter or the return type for a function definition shall not be an incomplete class type (possibly cv-qualified) unless the function definition is nested within the member-specification for that class (including definitions in nested classes defined within
the class).

Function call

[C++11: 5.2.2/4]: [..] When a function is called, the parameters that have object type shall have completely-defined object type. [ Note: this still allows a parameter to be a pointer or reference to an incomplete class type. However, it prevents a passed-by-value parameter to have an incomplete class type. —end note ] [..]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文