Rahul
Rahul

Reputation: 277

C++ Template: Partial template Function Specialization in template class

I want to specialize specific function in template class.

Eg:

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

when I do something like this, I get error saying multiple definition for fun2() Please let me why this wrong and also the correct way to implement this.

Upvotes: 3

Views: 512

Answers (3)

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361412

I would suggest the following approach. Define a private function template called implementation to handle the general case, and overload (not specialize) implementation to handle the specific case when T=char*. Then from fun2(), call implementation passing a third argument as shown below. The correct implementation will be selected based on the template argument 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*
        }
};

The third argument of type selector<T> (or selector<char*>) helps selecting the correct implementation.

Upvotes: 4

iammilind
iammilind

Reputation: 69988

Your method fun2() is not a template method as itself, though it's a member of a template class. I don't find the proper technical term but in simple words, specializing fun2() will create an effect of a normal function definition. Putting the definition in header file will give you multiple definition error.

To solve this problem, just put an inline keyword and the linker error will go away!

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

Edit: This solves the linker error. But still you cannot use the A<char*>::fun2. Ultimately it boils down to the very fact that you need to specialize the whole class A<char*> or overload the fun2(char*, char*) within A<T>

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

Upvotes: 2

Nim
Nim

Reputation: 33655

Split your code accordingly and it should work, for example:

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

Compile and link, and it should do the right thing...

Upvotes: 1

Related Questions