嵌套类中的别名模板

aliased templates in nested classes

本文关键字:别名 嵌套      更新时间:2023-10-16

我正试图从c的实例开始获得T2<B>的模板别名。

template<typename A>
struct T1
{
   template<typename B>
   struct T2{};
};
template<typename A>
class C
{
   T1<A> t;
};
template<typename A>
using U1=decltype(C<A>::t);
template<typename A, typename B>
using U2=typename U1<A>::T2<B>;

我得到一个编译失败的gcc 4.8:

gg.cc:18:28: error: expected ‘;’ before ‘<’ token
 using U2=typename U1<A>::T2<B>;

我在每个合理的位置都使用了typename关键字,但无法编译U2定义。

这里的正确语法是什么?如果我能得到U2的定义,而不用用到U1,那就更好了

您需要使用template消歧符告诉编译器将T2解析为模板的名称(随后的<>作为相应模板参数的分隔符):

    template<typename A, typename B>
    using U2=typename U1<A>::template T2<B>;
//                           ^^^^^^^^

下面是一个编译的实例。

在这里您可以找到关于何时应该使用template消歧器(以及typename消歧器,尽管您似乎知道那一个)的更多信息。

当编译器编译以下代码时:

template<typename A, typename B>
using U2=typename U1<A>::T2<B>;

在它读取嵌套的名称说明符U1<A>::之后,它不知道它在U1的哪个专门化中,因为A是未知的。每个U1专门化可能完全不同,这取决于A是什么。所以它不知道T1是什么样的名字。特别是它不知道它是否是模板名。(例如,U1<int>::T1可能与U1<char>::T1完全不同)

因此,您需要在T1之前使用template关键字来显式地告诉编译器T1将成为模板名称。