2

我正在尝试获取T2<B>从 C 实例开始的模板别名。

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 ‘&lt;’ token
 using U2=typename U1<A>::T2<B>;

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

这里的正确语法是什么?如果我能在不求助于 U1 的情况下得到 U2 的定义,那就更好了。

4

2 回答 2

4

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

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

这是一个编译的实时示例

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

于 2013-05-01T10:11:37.947 回答
1

当编译器编译以下内容时:

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。)

出于这个原因,您需要使用关键字 before明确告诉编译器T1将成为模板名称。templateT1

于 2013-05-01T14:52:07.847 回答