3

我有一个关于 C++ 模板专业化的问题,我希望这里有人可以提供帮助。我有一个有 3 个模板参数的类:

template<class A, class B, class C>
class myClass {

public:
  void myFunc();
};

我想要做的是编写 myFunc 的几个版本,专门用于类型 C,但对类型 A 和 B 是通用的。所以我不想要这样的完全模板化的函数:

template<class A, class B, class C>
void myClass<A, B, C>::myFunc()
{
  // function code here
}

而且我不想要像这样的完全专业化的功能

void myClass<int, int, int>::myFunc()
{
  // code goes here
}

相反,我想做一些类似于

template<class A, class B>
void myClass<A, B, int>::myFunc()
{
  // code goes here
}

这个想法是,如果类类型 C 是 int,我会调用一个版本的 myFunc(),如果类类型 C 是 double,我会调用不同版本的 myFunc。我已经尝试了很多不同的模板专业化语法组合(这里列出的太多了),但似乎没有一个可以编译。

有人可以在这里指出我正确的方向吗?在此先感谢您的帮助。

迈克尔

4

2 回答 2

6

您可以编写函数模板和重载,并将工作委托给它:

template<class A, class B, class C>
class myClass 
{
   //resolver doesn't need to define anything in it!
   template<class> struct resolver {}; //empty, yet powerful!
public:
  void myFunc() 
  {
       doFun(resolver<C>());
  }

  //this is a function template
  template<typename X>
  void doFun(const resolver<X> & )
  {
      //this function will get executed when C is other than int
      //so write your code here, for the general case
  }

  //this is an overload, not a specialization of the above function template!
  void doFun(const resolver<int> & ) 
  {
      //this function will get executed when C = int
      //so write your code here, for the special case when C = int
  }
};

注意一个重点:doFun(const resolve<int>& )是一个重载函数,它不是函数模板的特化。如果专门化封闭类模板,就无法专门化成员函数模板。

阅读这些文章:

于 2011-06-03T15:26:04.610 回答
0

如@Nawaz 所示,在解析器类型上调度是恕我直言的最佳方式。另一种选择是将该函数的实际实现移到类之外,在它自己的结构内,使其成为静态并部分专门化结构。在课堂上,调用它。当然,如果它访问 的私有部分myClass,你需要使它friend

template<class A, class B, class C>
class myClass;

template<class A, class B, class C>
struct myClassFuncs{
  typedef myClass<A,B,C> class_type;

  static void myFunc(class_type* self){
    // generic for everything ...
  }
};

template<class A, class B>
struct myClassFuncs<A,B,int>{
  typedef myClass<A,B,int> class_type;

  static void myFunc(class_type* self){
    // specialized on C == int ...
  }
};

// and so on ...

template<class A, class B, class C>
class myClass{
  typedef myClassFuncs<A,B,C> func_holder;
  friend class func_holder;
public:
  void myFunc(){
    func_holder::myFunc(this);
  }
};

虽然这会导致类和专业版本中有很多包装器......

另一个可以说是相当疯狂的想法是在类中没有函数而是函子。那些得到专业化然后被调用。这更冗长,但允许更好地访问您想要专门化的功能。但是,如果他们想访问私人部分,您现在需要让他们都成为朋友。:/

template<class A, class B, class C>
class myClass;

template<class A, class B, class C>
class myClass_myFunc{
  typedef myClass<A,B,C> class_type;
  class_type* const _self;

public:
  myClass_myFunc(class_type* self)
    : _self(self)
  {}

  void operator() const{
    // generic logic here
  }
};

template<class A, class B>
class myClass_myFunc<A,B,int>{
  typedef myClass<A,B,int> class_type;
  class_type* const _self;

public:
  myClass_myFunc(class_type* self)
    : _self(self)
  {}

  void operator() const{
    // specialized logic here
  }
};

template<class A, class B, class C>
class myClass{
  friend class myClass_myFunc<A,B,C>;
public:
  myClass()
    : myFunc(this)
  {}

  const myClass_myFunc<A,B,C> myFunc;
};
于 2011-06-03T15:35:46.600 回答