2016-06-21 1 views
2

내 현재 코드는 같습니다 Code here내부 템플릿 클래스를 외부 템플릿 클래스 유형으로 가져 오는 방법은 무엇입니까? 다음과 같은

내가 템플릿 ClassOuterTypeDTypeA, TypeB, TypeC의 모든 유형과 다른이 될 수있는 중첩 템플릿 ClassInnerBase을 보유하고 있습니다. 또한 ClassInnerDerivedClassInnerBase에서 상속 받아 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); 
} 

위의 코드는 아마 실제로 당신이 원하는 일을하지 않습니다하지만 좋은 출발점이라고 생각 ...

관련 문제