2012-10-10 39 views
6

這裏的情景:如何從類定義中將類模板作爲模板引用?

template <template <typename> class T, typename V> 
struct parent { 
    void do_something(); 
}; 

template <typename V> 
struct child : public parent<child, V> { 
    void do_something(V argument); 
    using parent<child, V>::do_something; // C3200: invalid template argument for template parameter 'IMPL', expected a class template 
}; 

上面的代碼無法編譯在給定的錯誤給定線(MSVC 9.0)。但是,如果我寫這篇文章不是,類定義之外的child

template <typename V> 
struct parent_identity_meta { 
    typedef typename parent<child, V> type; // no error! 
}; 

我現在可以成功做到以下幾點,內child

using parent_identity_meta<V>::type::do_something; 

我知道有一個限制(緩解了C + +11),你不能對模板進行typedef,但我不認爲這就是我在這裏遇到的情況,否則parent_identity_meta中的typedef將會失敗。似乎child指的是模板,當它不在其自己的類定義中時,以及類從其自身內部生成

這是很容易理解的(不得不寫的child<V>每一次將是痛苦的);但有沒有什麼方法可以覆蓋這種行爲?

+1

你試過':: child'嗎? –

+0

我無法解釋錯誤信息,但我注意到'do_something'是私人的。我認爲這也是一個問題。 – jogojapan

+0

@SethCarnegie:爲我解決了這個問題。我不知道爲什麼。哦,其實我認爲我知道了(: – Mankarse

回答

5

這是C++ 03和C++ 11彼此不同的地方。該標準的相關部分是[temp.local]/1。在C++ 03中,其狀態如下:

與正常(非模板)類相似,類模板具有注入類名(子句9)。注入類名可以使用或不使用模板參數列表。在沒有template-argument-list的情況下使用它時,它相當於注入的類名,後面跟着包含在<>中的類模板的模板參數。當它與模板參數列表一起使用時,它指向指定的類模板特化,它可能是當前的特化或另一種特化。

這意味着child(無任何模板參數)指的是專業化child<V>。在C++ 11中,它改爲:

與正常(非模板)類相似,類模板具有注入類名(第9章)。注入的類名稱可以用作模板名稱或類型名稱。當它與模板參數列表一起使用時,作爲模板模板參數的模板參數或作爲朋友類模板聲明的詳細類型說明符中的最終標識符時,它引用類模板本身。否則,它相當於模板名稱,後面跟着包含在<>中的類模板的模板參數。

特別注意When it is used ... as a template-argument for a template template-parameter ... it refers to the class template itself.。這意味着在C++ 11中,你的代碼是正確的。

+0

啊,打我幾秒鐘:) –

+0

非常感謝參考和C++ 11的信息。 MSVC9不做C++ 11,MSVC10做一些。我來回切換 - 我可能在MSVC10中完成了這一切,並沒有注意到它沒有工作。 –

+0

哈哈,謝謝@SethCarnegie ......我打算讓你升職,因爲真的,你首先得到了答案:)謝謝你們兩位。 –