模板模板参数可以默认引用其他模板类型参数吗?

时间:2014-09-12 14:58:47

标签: c++ templates template-templates

我试图做以下事情:

template <typename T>
struct A
{
    template <typename U>
    struct AA
    {
    };
};

template <typename V, template <typename> class W = A<V>::AA> // Causes C3202
struct B
{
};

但Visual Studio 2010编译器吐出:

错误C3202:&#39; AA&#39; :模板参数&#39;&#39;的无效默认参数,预期类模板

如果我用以下模板替换B:

// Replace "T" with "int"
template <typename V, template <typename> class W = A<int>::AA>
struct B
{
};

代码编译得很好,但不是我想要的。如果原始的不是合法的C ++,是否有替代方案为&#34; B&#34;的用户提供类似的界面。模板?

2 个答案:

答案 0 :(得分:3)

您的代码不是有效的C ++代码。请参阅下面的引文。


C ++ 03

  

14.2模板专精的名称[temp.names]

     

14.2 / 4

     

成员模板专精的名称出现在后缀表达式中的.->之后,或 nested-name-specifier 在 qualified-id 中,postfix-expression或qualified-id显式依赖于template-parameter(14.6.2),成员模板名称必须以关键字{{1}为前缀}。否则,假定该名称命名非模板。

     

14.2 / 5

     

如果以关键字template为前缀的名称不是成员模板的名称,则该程序格式错误。 [注意:关键字template可能不适用于类模板的非模板成员。]此外,成员模板的名称不应以关键字template作为前缀,如果 postfix-expression qualified-id 不会出现在模板的范围内。 [注意:template前缀的情况一样,在不是绝对必要的情况下允许使用typename前缀;即,当template->左侧的表达式或嵌套名称说明符不依赖于模板参数。]


C ++ 11

  

14.2模板专精的名称[temp.names]

     

14.2 / 4

     

成员模板专精的名称出现在后缀表达式中的..之后或嵌套名称说明符在 qualified-id 中, postfix-expression 的对象表达式依赖于类型或嵌套名称说明符在< em> qualified-id 是指依赖类型,但名称不是当前实例化的成员(14.6.2.1),成员模板名称必须以关键字->作为前缀。否则,假定该名称命名非模板。

     

14.2 / 5

     

以关键字template为前缀的名称应为 template-id ,或者名称应引用类模板。 [注意:关键字template可能不适用于类模板的非模板成员。 - 结束注释] [注意:template前缀的情况一样,如果不严格,则允许使用typename前缀必要;即,当嵌套名称说明符template->左侧的表达式不依赖于模板参数时,或者使用不会出现在模板的范围内。 - 结束记录] [示例:

.
     

- 结束示例]


符合标准的代码

因此,在这种情况下正确的语法是:

// ...

template <class T> struct B {
  template <class T2> struct C { };
};

// OK: T::template C names a class template:
template <class T, template <class X> class TT = T::template C> struct D { };

D<B<int> > db;

不幸的是 VC2010 也不了解有效的语法。

答案 1 :(得分:1)

根据您对&#34;类似&#34;的定义,您可以将B模板定义更改为

template <typename V, typename W = A<V>>
struct B
{
};

和struct B内部,您可以访问内部模板

W::template AA< some_type >

但是,您的用户需要提供类似AA的模板,就像您的struct A一样。

您还可以降低对编译器兼容性的要求,并且需要MSVC 2013 +。