模板方法和默认模板参数

lrl*_*eon 9 c++ templates scope-resolution default-arguments c++11

我的问题可以通过以下代码恢复:

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() {}

};
Run Code Online (Sandbox Code Playgroud)

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> 
Run Code Online (Sandbox Code Playgroud)

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

显然(我认为),编译器将其C2<T>视为默认参数而不是C2(不<T>).因此,当它找到指令失败时因为类型C2<T>不匹配Container.

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

我的问题:

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

提前致谢

莱昂德罗

Tem*_*Rex 9

我认为Clang是正确的,并且g ++是错误的,引用标准草案(大胆强调是我的)

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

1与普通(非模板)类一样,类模板具有注入类名(第9节).injectclass-name可以用作模板名称或类型名称.当它与template-argument-list一起使用时,作为模板模板参数的模板参数,或者作为友元类模板声明的详细类型特征中的最终标识符,它指的是类模板本身.否则,它等同于template-name,后跟<>中包含的类模板的template-parameters.

您可以使用::范围解析运算符将g ++击败为提交

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

};
Run Code Online (Sandbox Code Playgroud)

实例.