2013-09-25 129 views
9

我的問題可以通過下面的代碼段恢復:模板法和默認模板參數

template <typename T> struct C2; 

template <typename T> 
struct C1 
{ 
    template <typename Type, 
     template <typename Ti> class Container = C2> 
    void m() {} 
}; 


template <typename T> 
struct C2 
{ 
    template <typename Type = int, 
     template <typename Ti> class Container = C2> // <-- Here is the problem! 
    void m() {} 

}; 

GNU編譯器,版本4.8.1失敗,出現以下消息:

test-temp.C:16:47: error: invalid use of type ‘C2<T>’ as a default value for a template template-parameter 
     template <typename Ti> class Container = C2> 

它指的是方法C2 :: m的默認模板參數C2。

顯然(這是我的意見),編譯器看到C2<T>作爲默認參數,而不是C2(沒有<T>)。因此,當它發現指令失敗時,因爲類型C2<T>Container不匹配。

但是,鏗鏘++,只是爲了完全相同的代碼,編譯好!

我的問題:

  1. 哪個編譯器有真相?
  2. 是否有一些替代方案與gnu編譯器的當前版本表達相同的意義?

在此先感謝

萊昂德羅

+0

g ++是錯誤的,鏗鏘是正確的,也是模板模板中的名稱是可選的 – aaronman

回答

9

我覺得鐺是正確的,和g ++是錯誤的,從標準草案報價(粗體強調的是我的)

14.6.1本地聲明的名稱[temp.local]

1與正常(非模板)類一樣,類模板有一個 注入類名(第9章)。注入的類名稱可以用作模板名稱或類型名稱的 。當它與一個 模板參數列表,作爲模板參數的模板 模板參數使用,或作爲 的網絡最終identi網絡呃闡述-typespeci朋友類模板聲明的網絡連接呃,這 指類模板本身。否則,它相當於 模板名稱,後面跟着<>中包含的類 模板的模板參數。

可以使用::範圍解析運算符打G ++就範

template <typename T> 
struct C2 
{ 
    template <typename Type = int, 
     template <typename Ti> class Container = ::C2> 
               // ^^ <-- here is the solution! 
    void m() {} 

}; 

Live Example

+0

輝煌! ......及時。謝謝! – lrleon

+0

@Irleon很高興得到了幫助。歡迎來到Stackoverflow! – TemplateRex

+1

@TemplateRex我希望無論是Irleon還是你檢查過GCC是否有這個或創建的錯誤報告?這很好,但它沒有得到固定的東西。我通常鏈接到bugzilla讓人們知道,以便稍後可以檢查問題修復的版本。 (另:+1) –

0

那麼TemplateRex的答案中的14.6.1引用是否意味着G ++是正確的(並且Clang和VC++是錯誤的)來接受它,因爲它使用X作爲模板參數的模板參數?

template< template<typename> class T > 
class factory { }; 

template< typename T > 
class X 
{ 
     friend class factory<X>; // *** 
}; 

int main() 
{ 
} 

在這個例子中,G ++將X視爲類模板的名稱,而Clang和VC++將它視爲注入的類名。