首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >模板方法和默认模板参数

模板方法和默认模板参数
EN

Stack Overflow用户
提问于 2013-09-25 19:01:03
回答 2查看 637关注 0票数 9

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

代码语言:javascript
复制
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版本出现以下消息失败:

代码语言:javascript
复制
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不匹配。

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

我的问题:

  1. 哪个编译器有真相?
  2. 是否有其他方法来表达与当前版本的gnu编译器相同的意义?

提前感谢

莱安德罗

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-25 19:47:10

我认为Clang是正确的,g++是错误的,引用了标准草案的话(粗体强调是我的)

14.6.1本地声明的名称temp.local

和普通(非模板)类一样,类模板有一个注入的类名(第9条)。注入类名可以用作模板名或类型名称。当它与模板-参数列表一起使用时,作为模板参数的模板参数,或者作为朋友类模板声明的详细的- thefier中的final identifier时,它引用类模板本身。否则,它等同于<>中包含的类模板的模板名和模板参数。

您可以使用::作用域解析操作符来击败g++提交

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

};

Live Example

票数 9
EN

Stack Overflow用户

发布于 2013-09-26 09:26:44

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

代码语言:javascript
复制
template< template< typename > class T >
class factory { };

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

int main()
{
}

在本例中,G++将X视为类模板的名称,而Clang和VC++则将其视为注入的类名。

编辑:clang5.0.0现在接受代码,与G++和EDG一样。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19013071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档