Шаблон C ++: Частичная специализация функции шаблона в классе шаблона - PullRequest
3 голосов
/ 17 октября 2011

Я хочу специализировать определенную функцию в классе шаблона.

Например:

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 ]

4 голосов
/ 17 октября 2011

Я бы предложил следующий подход. Определите шаблон функции private с именем implementation для обработки общего случая и перегрузка ( не specialize ) 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*
        }
};

Третий аргумент типа selector<T> (или selector<char*>) помогает выбрать правильную реализацию.

2 голосов
/ 17 октября 2011

Ваш метод 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*
  }
};
1 голос
/ 17 октября 2011

Разделите ваш код соответственно, и он должен работать, например:

хиджры

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

Компиляция и ссылка, и она должна делать правильные вещи ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...