2013-09-25 131 views
9

我的问题可以通过下面的代码段恢复:模板法和默认模板参数

template <typename T> struct C2; 

template <typename T> 
struct C1 
{ 
    template <typename Type, 
     template <typename Ti> class Container = C2> 
    void m() {} 
}; 


template <typename T> 
struct C2 
{ 
    template <typename Type = int, 
     template <typename Ti> class Container = C2> // <-- Here is the problem! 
    void m() {} 

}; 

GNU编译器,版本4.8.1失败,出现以下消息:

test-temp.C:16:47: error: invalid use of type ‘C2<T>’ as a default value for a template template-parameter 
     template <typename Ti> class Container = C2> 

它指的是方法C2 :: m的默认模板参数C2。

显然(这是我的意见),编译器看到C2<T>作为默认参数,而不是C2(没有<T>)。因此,当它发现指令失败时,因为类型C2<T>Container不匹配。

但是,铿锵++,只是为了完全相同的代码,编译好!

我的问题:

  1. 哪个编译器有真相?
  2. 是否有一些替代方案与gnu编译器的当前版本表达相同的意义?

在此先感谢

莱昂德罗

+0

g ++是错误的,铿锵是正确的,也是模板模板中的名称是可选的 – aaronman

回答

9

我觉得铛是正确的,和g ++是错误的,从标准草案报价(粗体强调的是我的)

14.6.1本地声明的名称[temp.local]

1与正常(非模板)类一样,类模板有一个 注入类名(第9章)。注入的类名称可以用作模板名称或类型名称的 。当它与一个 模板参数列表,作为模板参数的模板 模板参数使用,或作为 的网络最终identi网络呃阐述-typespeci朋友类模板声明的网络连接呃,这 指类模板本身。否则,它相当于 模板名称,后面跟着<>中包含的类 模板的模板参数。

可以使用::范围解析运算符打G ++就范

template <typename T> 
struct C2 
{ 
    template <typename Type = int, 
     template <typename Ti> class Container = ::C2> 
               // ^^ <-- here is the solution! 
    void m() {} 

}; 

Live Example

+0

辉煌! ......及时。谢谢! – lrleon

+0

@Irleon很高兴得到了帮助。欢迎来到Stackoverflow! – TemplateRex

+1

@TemplateRex我希望无论是Irleon还是你检查过GCC是否有这个或创建的错误报告?这很好,但它没有得到固定的东西。我通常链接到bugzilla让人们知道,以便稍后可以检查问题修复的版本。 (另:+1) –

0

那么TemplateRex的答案中的14.6.1引用是否意味着G ++是正确的(并且Clang和VC++是错误的)来接受它,因为它使用X作为模板参数的模板参数?

template< template<typename> class T > 
class factory { }; 

template< typename T > 
class X 
{ 
     friend class factory<X>; // *** 
}; 

int main() 
{ 
} 

在这个例子中,G ++将X视为类模板的名称,而Clang和VC++将它视为注入的类名。