2016-11-09 64 views
2

我有以下模板類&示例類:如何設置,作爲默認模板參數,嵌套模板類instanciation取決於其他參數

template<typename A, typename B, typename C = typename A::Nested<B>> 
struct X 
{ 
    X() 
    { 
     std::cout << "A is : " << A::who() << std::endl; 
     std::cout << "B is : " << B::who() << std::endl; 
     std::cout << "C is : " << C::who() << std::endl; 
    } 
}; 

struct Bsample 
{ 
    static const char* who() { return "Bsample"; } 
}; 

struct Asample 
{ 
    template<typename B> 
    struct Nested; 
    template<> 
    struct Nested<Bsample> 
    { 
     static const char* who() { return "Asample::Nested<Bsample>"; } 
    }; 
    static const char* who() { return "Asample"; } 
}; 

當使用VCl 4,以上代碼編譯就好,併產生預期的行爲爲X<Asample, Bsample>默認模板參數CAsample::Nested<Bsample>的實例。

然而,GCC 5.1編譯時,我得到以下錯誤:

prog.cpp:4:65: error: expected '>' before '<' token 
template<typename A, typename B, typename C = typename A::Nested<B>> 
                   ^

我試了幾個組合,以申報模板參數C默認值,使用templatetypename,...但沒有成功地使用GCC編譯此代碼。

如何使此代碼符合C++標準並使用GCC進行編譯?

感謝您的幫助

編輯:除了從TartanLlama

除了從TartanLlama接受的答案接受的答案,我也只好終止模板參數brakets之間插入空白(空間) :

template<typename A, typename B, typename C = typename A::Nested<B> > 
//          blank (space) added here^

否則,GCC將發出以下錯誤(未指定選項-std=c++11時):

error: spurious '>>', use '>' to terminate a template argument list 
template<typename A, typename B, typename C = typename A::template Nested<B>> 
                      ^
+0

我投票重新開放,因爲這不僅僅是'template'和'typename',它似乎像OP知道他們的使用,但不知道如何在這裏應用它。 – TartanLlama

+0

@TartanLlama:可悲的是,有些人比光明更快地解決問題,甚至沒有把它們讀到最後......(我有一個想法,迄今爲止誰已經關閉了我。)謝謝你重新開放。 – shrike

回答

4

同時需要typenametemplate這裏:

template<typename A, typename B, typename C = typename A::template Nested<B>> 

template說比A::Nested是一個模板,以及typenameA::Nested<B>名稱的類型。

您還需要移動的Asample::Nested專業化出Asample定義的:

struct Asample 
{ 
    template<typename B> 
    struct Nested; 

    static const char* who() { return "Asample"; } 
}; 

template<> 
struct Asample::Nested<Bsample> 
{ 
    static const char* who() { return "Asample::Nested<Bsample>"; } 
}; 

Live demo

+0

我實際上是在你的答案中嘗試聲明默認的模板參數,但是仍然有一個來自gcc的奇怪錯誤:'spurious'>>',使用'>'來終止模板參數列表。我只是明白,gcc確實將最終'>>'解釋爲提取操作符;在關閉的剎車之間插入一個空白處理問題。 (如果您願意,您可以更新您的答案以提及此問題;否則我會更新我的問題。)無論如何,我會接受您的答案,因爲它爲我的問題提供了兩個主要修復程序。謝謝。 – shrike

+0

@shrike是的,你以前需要在它們之間有一個空格,但是它在C++ 11中是固定的。 – TartanLlama

1

你需要告訴編譯器Nested是一個模板:

template<typename A, typename B, typename C = typename A::template Nested<B>> 
struct X 
{ 
    // ... 

無論如何,由於不同的錯誤,您的代碼將無法編譯:

error: explicit specialization in non-namespace scope 'struct Asample' 
    template<> 

您需要在名稱空間範圍內專門設置Nested