专门研究 C++ 中的类型子集。模板

发布于 2024-11-13 21:42:07 字数 823 浏览 3 评论 0原文

我有一个关于 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是双重的,我会调用不同的版本myFunc 的。我已经尝试了很多不同的模板专业化语法组合(太多,无法在此列出),但似乎没有一个可以编译。

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

迈克尔

I have a question about template specialization in C++, and I am hoping someone here can help. I have a class that has 3 template parameters:

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

public:
  void myFunc();
};

What I want to do is write several versions of myFunc that specialize on, say, type C, but are generic for types A and B. So I do NOT want the fully templated function like this:

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

and I do NOT want a fully specialized function like this

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

Instead, I want to do something that would be similar to

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

The idea is that if class type C is int, I would call one version of myFunc(), and if class type C is double, I would call a different version of myFunc. I've tried lots of difference combinations of template specialization syntaxes (too many to list here), and none seems to compile.

Could someone possibly point me in the right direction here? Thanks in advance for your help.

Michael

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青衫儰鉨ミ守葔 2024-11-20 21:42:07

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

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(constresolve&)是一个重载函数,它不是函数模板。如果不专门化封闭类模板,您就无法专门化成员函数模板。

阅读这些文章:

You can write a function template, and an overload, and delegate the work to it:

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
  }
};

Note an important point : doFun(const resolve<int>& ) is an overloaded function, its not a specialization of the function template. You cannot specialize member function template without specializing the enclosing class template.

Read these articles:

软甜啾 2024-11-20 21:42:07

正如 @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;
};

Dispatching on a resolver type as @Nawaz shows is IMHO the best way. Another option would be to move the real implementation of that function outside of the class, inside its own struct, make it static and partially specialize the struct. Inside the class, call that. Of course, if it accesses private parts of myClass, you need to make it 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);
  }
};

Though that leads to a lot of wrappers in the class and the specialized versions...

Another idea, which can be said to be pretty crazy, is to not have functions in the class but functors. Those get specialized and then called. This is more verbose, but allows a better access to which functions you want to specialize. Though, if they want to access private parts, you now need to make all of them friends. :/

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;
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文