2013-01-12 21 views
4

似乎铛++(我试过铛3.2)模板把模板类的名字作为实例化的类,而不是为类范围内的任何occurence的模板。例如,以下代码铛++ - 治疗模板类的名称作为类范围

template <template <class> class T> 
class A {}; 

template <typename T> 
class B { 
    A<B> member; 
    // ^---- clang++ treats B as an instantiated class 
     // but I want it to be a template here 
     // this code could compile in g++ 
}; 

int main() 
{ 
    B<int> b; 
    return 0; 
} 

我应该怎样编译它?

回答

3

C++ 03

解决B这种方式(称为注入类名,每类包括模板实例的隐式声明的部件)的目的是作为一个方便。我从来没有见过这样的方式!

要解决,通过增加::资格以前它的名称(如果有必要,该命名空间的名称)。

template <typename T> 
class B { 
    A< ::B> member; // whitespace required to prevent digraph; see comments 
}; 

C++ 11

C++ 11§14.6.1/ 1指定(重点煤矿)

像正常(非模板)类,类模板已注入的-class-name(第9章)。注入的类名称可以用作模板名称或类型名称。当它与一个模板参数列表,作为模板参数的模板的模板参数,或作为朋友类模板声明的阐述-类型 - 指定符的最后标识符一起使用,它指的是类模板本身。否则,它相当于模板名称,后面跟着包含在<>中的类模板的模板参数。

因此,如果在C++ 11下发生这个问题,它是一个编译器错误。如上所述的解决方法。

注 - 为了比较,在C++ 03的相应段落是

像正常(非模板)类,类模板有一个注入的类名(第9节)。注入类名可以使用或不使用模板参数列表。在没有template-argument-list的情况下使用它时,它相当于注入的类名,后面跟着包含在<>中的类模板的模板参数。当它与模板参数列表一起使用时,它指向指定的类模板特化,它可能是当前的特化或另一种特化。

正如您所看到的,已经有一种特殊情况允许标识符是类或模板,具体取决于它是否出现在模板名称中。他们只是增加了几个案例。

+0

@neuront:哇...从来不知道'<:'...+1到雅都 – Cornstalks

+1

@Cornstalks,如果您有兴趣,对于那些以前没有[钥匙]的人来说,这是一个二合字母。 – chris

+0

@neuront'<::'现在是词法分析器的特例,但它是C++ 11中的一项新功能。 – Potatoswatter

1

这是不符合标准的行为的C++ 11,因为C++ 11表示,注入的类名(也就是类体中自动声明的名字)是一个模板时,它被传递给一个模板的模板参数。所以你的代码只能在C++ 03实现中失败。

但是没有必要现在就打开这个bug报告。我已经完成了它。

+0

+1有趣的知道,它在14.6.1/1。 – Potatoswatter

+0

*“但是现在不需要打开关于这个的错误报告,我已经完成了它的工作。”*,这是典型的呃.. :-) –