Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 360
Rahul Avatar asked Apr 14 '26 16:04

Rahul


2 Answers

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.

like image 113
Nawaz Avatar answered Apr 16 '26 05:04

Nawaz


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*
  }
};
like image 31
iammilind Avatar answered Apr 16 '26 06:04

iammilind