3

下面的代码工作正常:

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

让 line-1 和 line-2 移到里面main()。该函数不会受到影响,但class A前向声明不起作用并给出编译器错误

template<class T> class X错误:使用本地类型的模板参数main()::A

4

2 回答 2

4

您可以观察到正在发生的事情,因为在 C++ 中,您可以在函数中定义类。所以,如果你放在class A;main,你就是在这个函数的范围内(即class main::A)前向声明一个类,而不是在全局范围内(class A)。

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

于 2012-10-06T06:32:17.650 回答
2

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

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

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

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

这个问题在 C++11 中通过决定X<A>使用本地类型与在函数外部的匿名命名空间中声明A的相同,如A

namespace
{
    class A
    { };
}

int main()
{
    X<A>   vA;
}

因此,使用较新的编译器(或使用-std=cpp11选项),您可以使用本地类,我们也知道它的含义。


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

于 2012-10-06T10:00:35.693 回答