为什么在函数范围内不允许类前向声明​​?

时间:2012-10-06 06:23:13

标签: c++ class compiler-errors forward-declaration language-lawyer

下面的代码工作正常:

template<typename T> class X {};
class A;  // line-1
void foo();  // line-2
int main ()
{
  X<A> vA;
}
class A {};
void foo() {}

让第1行和第2行在main()内移动。该函数不会受到影响,但class A转发声明不起作用,并提供compiler error

  

错误:template<class T> class X的模板参数使用local   输入main()::A

2 个答案:

答案 0 :(得分:4)

您可以观察到的事情正在发生,因为在C ++中,您可以在函数内定义类。 因此,如果您将class A;放在main中,那么您正在声明此函数范围内的类(即class main::A),而不是全局范围(class A)。

因此,您最终使用未定义类(X<main::A>)的模板参数声明了类型为X的对象。

答案 1 :(得分:2)

  

错误:模板类X的模板参数使用本地类型main():: A

这是真正的问题 - 使用本地类型。在C ++ 03中,您不能使用本地类型作为模板参数,因为没有人知道如何命名结果类型。

如果你在几个重载函数中有多个class A(再次使用相同的名称),那么结果X<A>会是相同类型还是不同类型?你怎么把他们分开?

在C ++ 03中,标准传递了这个,并且只是说“不要那样做!”。

通过决定使用本地类型X<A>的{​​{1}}与在{1}}之外的匿名命名空间中声明的A相同,解决了C ++ 11中的问题功能,如

A

因此,使用较新的编译器(或使用namespace { class A { }; } int main() { X<A> vA; } 选项),您可以使用本地类,我们也知道它的含义。


但是,在函数内部声明一个类型仍然不同于在另一个范围内声明它的前向相同。它们只是不同的类型。