有没有办法确定模板类的模板参数类型?

时间:2015-01-21 15:33:18

标签: c++ templates

我有两个模板类,这些参数是在软件的不同层中决定的。 我必须在较低层使用的类是

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

我必须在上层使用的类是

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

我还可以创建“信息”。类

template <class LanguageId,
          class SomeInformCBSet>

typedef InformCBSet<SomeRoutineInfoId,
                    SomeErrorInfoId,
                    SomeLoadBarInfoId> SomeInformCBSet

我希望直接使用SomeInfoCBSet作为&#39; Info类的模板参数,从上层的SomeInfoCBSet获取(这是较低层类的类型)。

有什么方法可以实现吗? 感谢

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分: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;