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

时间:2012-02-11 15:12:37

标签: c++ language-lawyer

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

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数据成员定义的要求。)

2 个答案:

答案 0 :(得分:5)

参见8.​​3.5p9,其中列出了确切的规则。对于= delete定义,实现也是likely to accept incomplete parameter types,追溯性(由C ++委员会在DR决议中确定)。

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

答案 1 :(得分:0)

功能声明

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

7.1.1/9告诉我们,extern声明(在语义上类似于成员函数声明)是可以的,并且非规范地向我们显示此类声明中的类型可能不完整:

  

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

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
}
     

- 示例]

功能定义(感谢litb)

  

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

函数调用

  

[C++11: 5.2.2/4]: [..] 调用函数时,具有对象类型的参数应具有完全定义的对象类型。 [注意: this仍然允许参数成为指向不完整类类型的指针或引用。但是,它会阻止传值参数具有不完整的类类型。 -end note ] [..]