Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板参数默认值是否可以引用其他模板类型参数?_C++_Templates_Template Templates - Fatal编程技术网

C++ 模板参数默认值是否可以引用其他模板类型参数?

C++ 模板参数默认值是否可以引用其他模板类型参数?,c++,templates,template-templates,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 { }; 模板 结构A { 模板 结构AA { }; };

我正在尝试做如下事情:

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

template <typename V, template <typename> class W = A<V>::AA> // Causes C3202
struct B
{
};
模板
结构A
{
模板
结构AA
{
};
};
模板//C3202
结构B
{
};
但VisualStudio2010编译器指出:

错误C3202:“AA”:模板参数“”的默认参数无效,应为类模板

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

// Replace "T" with "int"
template <typename V, template <typename> class W = A<int>::AA>
struct B
{
};
//将“T”替换为“int”
模板
结构B
{
};

代码编译得很好,但不是我想要的。如果原始的不是合法的C++,是否有一个替代的方法为“B”模板的用户提供类似的接口?

取决于您对“相似”的定义,您可以将<代码> b>代码>模板定义更改为

template <typename V, typename W = A<V>>
struct B
{
};
但是,您的用户需要提供封装在类中的类似AA的模板,就像您的
结构a
一样


您也可以降低编译器兼容性的要求,要求MSVC 2013 + .< /p> 您的代码不是有效的C++代码。请参阅下面的引号


C++03 14.2模板专门化的名称[临时名称]

14.2/4

当成员模板专用化的名称出现在后缀表达式中的
->
之后,或在限定id中的嵌套名称说明符之后,并且后缀表达式或限定id显式依赖于模板参数时(14.6.2),成员模板名称的前缀必须为关键字
template
。否则,将假定该名称为非模板名称

14.2/5

如果以关键字
template
为前缀的名称不是成员模板的名称,则程序的格式不正确。[注意:关键字
template
可能不适用于类模板的非模板成员。]此外,如果后缀表达式或限定id未出现在模板范围内,则成员模板的名称不得以关键字
template
作为前缀。[注:与使用
类型名称
前缀的情况一样,如果不严格需要使用
模板
前缀,即
->
左侧的表达式或嵌套的名称说明符不依赖于模板参数,则允许使用
模板
前缀。]


C++11 14.2模板专门化的名称[临时名称]

14.2/4

当成员模板专用化的名称出现在后缀表达式中的
->
之后,或出现在限定id中的嵌套名称说明符之后,并且后缀表达式的对象表达式依赖于类型,或限定id中的嵌套名称说明符引用依赖类型时,但是名称不是当前实例化(14.6.2.1)的成员,成员模板名称必须以关键字
template
作为前缀。否则,将假定该名称为非模板名称

14.2/5

以关键字
template
为前缀的名称应为模板id或名称应指类模板。[注:关键字
template
不能应用于类模板的非模板成员。-结束注][注:与
类型名称
前缀的情况一样,
模板
前缀在并非严格必要的情况下是允许的;例如,嵌套的名称说明符或
->
左侧的表达式不依赖于模板参数,或者使用不出现在tem的范围内图版-尾注][示例:

/。。。
模板结构B{
模板结构C{};
};
//OK:T::template C命名一个类模板:
模板结构D{};
D分贝;
-[结束示例]


符合标准的代码 因此,在这种情况下,正确的语法是:

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

template <typename V, template <typename> class W = A<V>::template AA>
//                                                      ^^^^^^^^^^^
struct B
{
};
模板
结构A
{
模板
结构AA
{
};
};
模板
//                                                      ^^^^^^^^^^^
结构B
{
};

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

这在VS 2013上起作用。

模板引用的类型是什么?@Surt它如何将模板声明为模板参数。它告诉编译器
class W
是一个模板类类型,而不仅仅是一些任意类型。@DarkFalcon因此VS 2013有一个错误。这不是标准的-符合要求的代码。@构造函数:是。它也接受正确的语法。我最初在回答中建议这样做,但由于VS 2010的问题而将其删除。
// ...

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;
template <typename T>
struct A
{
    template <typename U>
    struct AA
    {
    };
};

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