2016-06-21 128 views
2

我當前的代碼看起來像如下:Code here如何讓內部模板類是外部模板類的類型?

我有一個模板ClassOuter和嵌套模板ClassInnerBase,其中TypeD可以是任何類型的TypeA, TypeB, TypeC並沒有其他的。此外,ClassInnerDerived應繼承ClassInnerBase並實施virtual const int Method(int id) = 0;

template<typename TypeA, typename TypeB, typename TypeC> 
class ClassOuter { 
public: 

    class ClassInnerBase { 
    public: 
     ClassInnerBase(int x) : 
       m_x(x) { 
     } 

     virtual const int Method(int id) = 0; 

    private: 
     int m_x; 
    }; 

    template<typename TypeD> 
    class ClassInnerDerived : public ClassInnerBase { 
    public: 
     ClassInnerDerived<TypeD>(const TypeD &object, int x) : 
       ClassInnerBase(x), m_object(object) { 

     } 

     // Implementation of ClassInnerBase::Method for type float 
     template<> 
     const int ClassInnerDerived<float>::Method(int id){ 
      return GetLookupID(id); 
     } 

     // Implementation of ClassInnerBase::Method for type double 
     template<> 
     const int ClassInnerDerived<double>::Method(int id){ 
      return GetLookupID(id); 
     } 


    private: 
     TypeD m_object; 
    }; 

    void DoSomething(const std::vector<ClassInnerBase> &inner_vec, int id); 

    const int GetLookupID(int id) const{ 
     return lookup[id]; 
    } 

private: 
    int lookup[100]; 
}; 

template<typename TypeA, typename TypeB, typename TypeC> 
void ClassOuter<TypeA, TypeB, TypeC>::DoSomething(const std::vector<ClassInnerBase> &inner_vec, int id){ 
    for(const auto &inner : inner_vec){ 
     inner.Method(id); 
    } 
} 


int main() 
{ 
    std::vector<typename ClassOuter<int, double, float>::ClassInnerBase> class_base_objects; 
    typename ClassOuter<int, double, float>::template ClassInnerDerived<float> class_inner_derived_object(0.2f, 1); 
    class_base_objects.push_back(class_inner_derived_object); 

    typename ClassOuter<int, double, float>::template DoSomething(class_base_objects, 1); 
} 

我最終得到的錯誤:

g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out 
main.cpp:30:18: error: explicit specialization in non-namespace scope 'class ClassOuter<TypeA, TypeB, TypeC>::ClassInnerDerived<TypeD>' 
     template<> 
       ^

我很卡在這裏,不知道如何解決這個錯誤。 此外,是否有任何關於實施的建議/意見/改進?

+0

你最好是在更好[代碼審查( http://codereview.stackexchange.com/)用於改進您的實現 – Rakete1111

+2

@ Rakete1111不,代碼評論不是*代碼被破壞的地方,因爲它在那裏是脫離主題的。他在正確的網站上詢問。 – syb0rg

+0

@ syb0rg我只是意味着改進點。對於實際的錯誤OP是在正確的網站 – Rakete1111

回答

0

由於你的編譯器說你不能明確(完全)專門化模板類的內部類。你正在做的更糟,因爲你試圖從內部類中分離出一個單獨的方法,這對於非嵌套的模板類來說是不可能的......你可以做的是通過添加額外的模板參數來默認值到你的內部班級,部分專門化整個內部班級。這實際上可以讓你測試模板參數是否是使用sfinae機制的給定類型(我在你的例子中測試過,如果內部模板參數是字面上的double或float,但你可以類似地測試它是否是外部模板類型之一還有),例如:

#include <iostream> 
#include <type_traits> 
#include <vector> 

template<typename TypeA, typename TypeB, typename TypeC> 
class ClassOuter { 
public: 

    class ClassInnerBase { 
    public: 
     ClassInnerBase(int x) : 
       m_x(x) { 
     } 

     virtual const int Method(int id) = 0; 

    private: 
     int m_x; 
    }; 

    template<typename TypeD, typename = void> 
    class ClassInnerDerived; 

    template<typename TypeD> 
    class ClassInnerDerived<TypeD, std::enable_if_t<std::is_same<TypeD, float>::value || std::is_same<TypeD, double>::value> >: public ClassInnerBase { 
    public: 
     // Implementation of ClassInnerBase::Method for type float 
     ClassInnerDerived(const TypeD &object, int x) : 
       ClassInnerBase(x), m_object(object) { 
     } 
     const int Method(int id){ 
      return GetLookupID(id); 
     } 
    private: 
     TypeD m_object; 
    }; 

    public: 

    //static void DoSomething(const std::vector<ClassInnerBase> &inner_vec, int id); 

    static const int GetLookupID(int id) { 
     return lookup[id]; 
    } 

private: 
    static int lookup[100]; 
}; 

template<typename TypeA, typename TypeB, typename TypeC> 
int ClassOuter<TypeA, TypeB, TypeC>::lookup[100]; 

/* 
template<typename TypeA, typename TypeB, typename TypeC> 
void ClassOuter<TypeA, TypeB, TypeC>::DoSomething(const std::vector<ClassInnerBase> &inner_vec, int id){ 
    for(const auto &inner : inner_vec){ 
     inner.Method(id); 
    } 
}*/ 


int main() 
{ 
std::vector<typename ClassOuter<int, double, float>::ClassInnerBase *> class_base_objects; 
    //typename ClassOuter<int, double, float>::template ClassInnerDerived<float> class_inner_derived_object(0.2f, 1); 
    class_base_objects.push_back(new ClassOuter<int, double, float>::ClassInnerDerived<float>(0.2f, 1)); //(class_inner_derived_object); 

    //typename ClassOuter<int, double, float>::template DoSomething(class_base_objects, 1); 
} 

上面的代碼可能實際上並沒有你想什麼,但我認爲這是一個很好的起點......