Использование специализации шаблонов в C ++ - PullRequest
1 голос
/ 09 января 2011

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

template <class input1, class input2, class output>

и вернуть сумму 2 чисел (целых / двойных).Однако, если я получу 2 целых числа, я хочу вернуть целочисленный тип, но для любых других комбинаций integer и double я всегда буду возвращать double.

Я пытаюсь сделать это без непосредственного использования оператора '+'но вместо этого есть следующие функции:

double add_double_double(double a, double b) {return (a+b);}
double add_int_double(int a, double b) {return ((double)(a)+b);}
int   add_int_int(int a, int b) {return (a+b);}

Ответы [ 5 ]

5 голосов
/ 09 января 2011

Если вы можете использовать C ++ 0x, вы можете сделать это:

template <typename T, typename U>
auto add(T lhs, U rhs) -> decltype(lhs+rhs)
{
    return lhs+rhs;
}
4 голосов
/ 09 января 2011

Не используйте шаблонную специализацию.Вместо этого используйте перегрузку.Специализированные функции сложны и редко нужны:

template <typename T1, typename T2>
double sum(T1 a, T2 b) { return a + b; }

int sum(int a, int b) { return a + b; }

Вторая версия будет вызываться тогда и только тогда, когда оба аргумента равны int;в противном случае будет названа первая версия.

0 голосов
/ 10 января 2011

Тип возвращаемого значения шаблона функции может зависеть от типов параметров шаблона.В вашем случае вы можете сделать что-то похожее на:

template <typename L, typename R>
struct sum_traits { typedef double return_type; };

template <>
struct sum_traits<int, int> { typedef int return_type; };

template <typename L, typename R>
typename sum_traits<L, R>::return_type
sum(L l, R r) { 
  typedef typename sum_traits<L, R>::return_type ret_t;
  return ret_t(l) + ret_t(r); 
}

Я не думаю, что явное приведение к ret_t когда-либо действительно необходимо в этом случае , но это демонстрируетбольше техники.

Это обрабатывает только целые числа, но идея может быть легко обобщена для обработки более сложных случаев.

0 голосов
/ 09 января 2011

Ответ на ваш вопрос находится в главе 15 книги C ++ .В этой главе приведен пример аккумулятора , в котором рассматривается ваш вопрос.Далее в этой главе речь пойдет об особенностях продвижения, где будет решаться проблема добавления двух разных типов, а также продвижения по типу адреса.

0 голосов
/ 09 января 2011

Это может быть то, что вам нужно:

#include <iostream>
using namespace std;

template <class input1, class input2, class output> output add(input1 n1, input2 n2) {
   return (output) n1 + (output) n2;
}

int main(int argc, char **argv) {

   cout << add<int, int, int>(1,1) << endl;
   cout << add<float, int, float>(1.1f,1) << endl;
   cout << add<int, float, float>(1,1.1f) << endl;
   cout << add<float, float, int>(1.1f,1.1f) << endl;

   return 0;
}

Результат:

quad: > ./a.out 
2
2.1
2.1
2
Sun 09 Jan 2011 12:57:57 PM MST

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