我试图做以下事情:
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;的用户提供类似的界面。模板?
答案 0 :(得分:3)
您的代码不是有效的C ++代码。请参阅下面的引文。
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
或->
左侧的表达式或嵌套名称说明符不依赖于模板参数。]
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 +。