2015-01-21 5 views
2

У меня есть два класса шаблонов, аргументы которых решаются в разных слоях программного обеспечения. Класс, который я должен использовать в нижнем слоеЕсть ли способ определить типы аргументов шаблона класса шаблона?

template <class RoutineInfoId, 
     class ErrorInfoId, 
     class LoadBarInfoId> 
class InformCBSet 

класса, который я должен использовать в верхнем слое

template <class LanguageId, 
      class RoutineInfoId, 
      class ErrorInfoId, 
      class LoadBarInfoId> 
class Info 

Я могу также создать класс «Info»

template <class LanguageId, 
      class SomeInformCBSet> 

тогда

typedef InformCBSet<SomeRoutineInfoId, 
        SomeErrorInfoId, 
        SomeLoadBarInfoId> SomeInformCBSet 

Я хочу получить (то есть типы класса нижнего уровня) из SomeInfoCBSet в верхнем уровне, используя SomeInfoCBSet в качестве аргумента шаблона непосредственно из класса Info.

Любой способ понять это? Благодаря

+0

У меня есть проблемы с пониманием вашего вопроса. Вы хотите получить аргументы шаблона из специализированной специализации? Как взять в 'Foo ' и получить 'A',' B' и 'C'? – Quentin

+0

да Квентин. точно – ataman

ответ

2

Вы можете использовать другой шаблон в качестве помощника для получения желаемого типа:

// Helper accepts two types: a language ID and an InformCBSet instantiation. This 
// declares the base template, but we need to specialize it, so there is no base 
// template implementation. 
template <typename, typename> 
struct InformCBSet_to_Info; 

// Specialization where the second argument is an InformCBSet instantiation. 
template <typename LanguageId, 
      typename RoutineInfoId, 
      typename ErrorInfoId, 
      typename LoadBarInfoId> 
struct InformCBSet_to_Info<LanguageId, InformCBSet<RoutineInfoId, 
                ErrorInfoId, 
                LoadBarInfoId>> 
{ 
    typedef Info<LanguageId, 
       RoutineInfoId, 
       ErrorInfoId, 
       LoadBarInfoId> info_type; 
}; 

typedef InformCBSet<SomeRoutineInfoId, 
        SomeErrorInfoId, 
        SomeLoadBarInfoId> SomeInformCBSet; 

typedef InformCBSet_to_Info<SomeLanguageId, SomeInformCBSet>::info_type SomeInfoType; 
+0

тоже понравилось. Благодарю. – ataman

5

Вы могли бы использовать это или что-то вроде этого:

template<typename T> struct InformCBSetTypes; 
template<typename T0, typename T1, typename T2> 
struct InformCBSetTypes<InformCBSet<T0, T1, T2> > { 
    typedef T0 RoutineInfoId; 
    typedef T1 ErrorInfoId; 
    typedef T2 LoadBarInfoId; 
}; 

Чтобы иметь возможность использовать typename InformCBSetTypes<SomeInformCBSet>::RoutineInfoId и т.д. в шаблоне Info класса. Для целей демонстрации:

#include <iostream> 
#include <string> 

template<typename T0, typename T1, typename T2> 
struct InformCBSet { }; 

template<typename T> struct InformCBSetTypes; 
template<typename T0, typename T1, typename T2> 
struct InformCBSetTypes<InformCBSet<T0, T1, T2> > { 
    typedef T0 RoutineInfoId; 
    typedef T1 ErrorInfoId; 
    typedef T2 LoadBarInfoId; 
}; 

int main() { 
    typedef InformCBSet<int, double, std::string> MySet; 

    // Note: To use these inside a template, you'll have to write "typename" 
    //  before them (as with all typedefs in dependent types) so that the 
    //  compiler knows to expect a type before it knows which specialization 
    //  of InformCBSetTypes it's ultimately going to use. 
    InformCBSetTypes<MySet>::RoutineInfoId i = 1;    // int 
    InformCBSetTypes<MySet>::ErrorInfoId d = 2.3;    // double 
    InformCBSetTypes<MySet>::LoadBarInfoId s = "Hello, world!"; // string 

    std::cout << i << ", " << d << ", " << s << std::endl; 
} 
+0

кажется очень удобным способом. спасибо – ataman

Смежные вопросы