Шаблоны для кода, который похож, но не идентичен? - PullRequest
6 голосов
/ 06 июня 2011

У меня есть набор функций, которые читают полностью идентично, за исключением одной строки кода, которая отличается в зависимости от типа входного параметра.

Пример:

void Func(std::vector<int> input)
{
   DoSomethingGeneral1();
   ...
   DoSomethingSpecialWithStdVector(input);
   ...
   DoSomethingGeneral2();
}

void Func(int input)
{
   DoSomethingGeneral1();
   ...
   DoSomethingSpecialWithInt(input);
   ...
   DoSomethingGeneral2();
}

void Func(std::string input)
{
   DoSomethingGeneral1();
   ...
   DoSomethingSpecialWithStdString(input);
   ...
   DoSomethingGeneral2();
}

Интереснокак я мог избежать этого дублирования, используя шаблоноподобный механизм.Если я правильно понимаю «специализацию», это не мешает иметь код специализированных функций дважды?

Ответы [ 5 ]

8 голосов
/ 06 июня 2011

здесь вы идете .. изменили параметры на ссылки, чтобы избежать копирования + убедитесь, что вы можете снова использовать измененные значения в Func ()

void DoSomethingSpecial( std::vector<int>& input ){}

void DoSomethingSpecial( int& input ){}

void DoSomethingSpecial( std::string& input ){}

template< typename T >
void Func( T input )
{
  DoSomethingGeneral1();
  DoSomethingSpecial(input);
  DoSomethingGeneral2();
}
4 голосов
/ 06 июня 2011

Я считаю, что нет необходимости в спецификациях шаблонов, вы можете использовать простую перегрузку функций, что-то вроде этого:

void DoSomethingSpecial(const std::vector<int>& input)
{
}

void DoSomethingSpecial(string s)
{
}

void DoSomethingSpecial(int input)
{
}
template <typename T>
void Func(const T& input)
{
  //DoSomethingGeneral1();
   DoSomethingSpecial(input);
   //DoSomethingGeneral2();
}

int main()
{
    std::vector<int> a;
    Func(a);
    Func("abc");
    Func(10);
}
3 голосов
/ 06 июня 2011

Что касается стиля, вы можете выделить части, которые отличаются как тривиальный шаблонный класс, который более легко специализируется. В качестве примера этой техники рассмотрим реализацию вашего любимого шаблона неупорядоченного набора (или hash_set). Такие реализации требуют, чтобы вы специализировали простой шаблон hash_key , если специализация еще не доступна. Они не требуют, чтобы вы специализировали весь контейнер.

Хотя ваш пример достаточно прост, чтобы просто специализировать всю функцию, в целом я бы реализовал Func в общем и специализировал бы DoSomethingSpecial примерно так:

template< class T >
void DoSomethingSpecial(T &input)
{
...
}

template< class T >
void Func(T input)
{
DoSomethingGeneral1();
...
DoSomethingSpecial(T);
...
DoSomethingGeneral2();
}

template<>
void DoSomethingSpecial(std::string &input)
{
...
}

template<>
void DoSomethingSpecial(int &input)
{
...
}
3 голосов
/ 06 июня 2011

Лучше всего сделать Func в качестве шаблона:

template<typename T>
void Func(T input);

И перегрузить DoSomethingSpecial...():

void DoSomethingSpecial(std::string);
void DoSomethingSpecial(int);
void DoSomethingSpecial(std::vector<int>);
1 голос
/ 06 июня 2011

Объявите универсальную версию, но определите только специализации:

template<class T>
void DoSpecificStuff( T& withWhat );

template<>
void DoSpecificStuff( int& withWhat)
{
    //implementation
}

template<>
void DoSpecificStuff( std::vector<int>& withWhat)
{
    //implementation
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...