C ++模板:模板类中的部分模板函数专业化

时间:2011-10-17 09:09:13

标签: c++ templates linker-errors template-specialization

我想专门化模板类中的特定功能。

例如:

template<class T>
class A   
{    
public :  
  void fun1(T val);  
  void fun2(T val1, T val2);
};

template <class T>
void A<T>::fun1(T val)
{
  // some task 1;
}


template <class T>
void A<T>::fun2(T val1, T val2)
{
  // some task 2;
}


template <>
void A<char*>::fun2(char* val1, char* val2)
{
  // some task 2 specific to char*;
}

当我做这样的事情时,我得到错误说fun2()的多个定义 请告诉我为什么这个错误以及实现这个的正确方法。

3 个答案:

答案 0 :(得分:4)

我建议采用以下方法。定义一个名为private的{​​{1}}函数模板来处理一般情况,重载 专门化){{ 1}}处理implementation时的特定情况。然后从implementation,调用T=char*传递第三个参数,如下所示。将根据模板参数fun2()

选择正确的implementation
implementation

类型T(或template<class T> class A { template<typename U> struct selector{}; public : void fun1(T val); void fun2(T val1, T val2) { //forward the call //a correct function will be selected automatically based on T implementation(val1, val2, selector<T>()); } private: template<typename U> void implementation(T & val1, T & val2, const selector<U> &) { //general case! } void implementation(T & val1, T & val2, const selector<char*> &) { //specific case when T = char* } }; )的第三个参数有助于选择正确的实现。

答案 1 :(得分:2)

您的方法fun2() 不是 template方法,尽管它是template类的成员。我找不到合适的技术术语,但简单来说,专门化fun2()会产生正常函数定义的效果。将定义放在头文件中会给你带来多个定义错误。

要解决此问题,只需添加inline关键字,链接器错误就会消失!

template <> inline // <----- 'inline' will prompt to generate only 1 copy
void A<char*>::fun2(char* val1, char* val2)
{
  // some task 2 specific to char*;
}

编辑:这解决了链接器错误。但是你还是不能使用A<char*>::fun2。归根结底,事实上你需要专门化整个class A<char*>重载 fun2(char*, char*) A<T>

template<class T>
class A
{
  // constructors
public:
  //...
  void fun2(char* val1, char* val2)
  {
    //specific case when T = char*
  }
};

答案 2 :(得分:1)

相应地拆分代码,它应该可以工作,例如:

A.H

template<class T>
class A   
{    
    public :  
        void fun1(T val);  
        void fun2(T val1, T val2);

};

template <class T>
void A<T>::fun1(T val)
{
  // some task 1;
}


template <class T>
void A<T>::fun2(T val1, T val2)
{
  // some task 2;
}

A.cpp

#include <iostream>
#include "A.h"

template <>
void A<char *>::fun2(char* val1, char* val2)
{
  // some task 2 specific to char*;
  std::cout << "char*::fun2" << std::endl;
}

Amain.cpp

#include <iostream>    
#include "A.h"

int main()
{
  A<char*> a;

  char* c= 0;
  char* d= 0;

  a.fun2(c, d);
}

编译和链接,它应该做正确的事情......