2013-05-01 60 views
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 ‘<’ token 
using U2=typename U1<A>::T2<B>; 

我有在每個明智的位置使用了typename關鍵字,但無法獲取U2定義進行編譯。

這裏的正確語法是什麼?如果我可以在不借助U1的情況下得到U2的定義,那將會更好。

回答

4

您需要使用template消歧告訴編譯器解析T2爲模板的名稱(以及隨後的<>作爲相應的模板參數的分隔符):

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

這裏是一個編譯live example

Here你可以找到時,你應該使用template消歧的一些詳細信息(和typename消歧爲好,雖然你似乎是知道的那一個)。

+0

我以前只在成員模板函數中看到過這個。謝謝,我從來沒有發現過我自己的。 – mirk 2013-05-01 10:13:41

+0

@mirk:很高興幫助。我在SO上添加了一個有用的Q&A的鏈接,詳細解釋如下。 – 2013-05-01 10:15:30

1

當編譯器編譯如下:

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

讀取嵌套名指定U1<A>::後,不知道它是其中的U1專業化,因爲A是未知的。每個U1 specializitonon可以完全不同,並取決於什麼A是。所以它不知道什麼樣的名字T1是。特別是它不知道它是否是模板名稱。 (例如U1<int>::T1可能是什麼U1<char>::T1是完全不同的。)

出於這個原因,你需要明確地告訴T1會通過T1之前使用template關鍵字是一個模板名稱,編譯器。