Функция, выполняющая схожие действия с данными различных типов

Рейтинг: 0Ответов: 2Опубликовано: 10.05.2011

Добрый день, подскажите пожалуйста как (и можно ли вообще это сделать) написать одну функцию выполняющую схожие действия(арифметические, логические и т.п.) над данными разных типов. Вид действия при возможности тоже неплохо бы менять(если язык это позволяет конечно). Если можно, приведите пару примеров

Ответы

▲ 6Принят

Класический пример сравнения двух переменных с предикатом: Два предиката:

template<class T>
class CMPLess
{
public:
    bool operator() (T a, T b) { return a<b; }
};

template<class T>
class CMPEqual
{
public:
    bool operator() (T a, T b) { return a==b; }
};

Функция сравнения:

template<class T, class CMP>
bool equal_if(T a, T b, CMP cmp)
{
    return cmp(a,b);
}

Вызов:

int a=2, b=3;
if (equal_if(a, b, CMPLess<int>()))
{ 
    // a<b
}
else
if (equal_if(a, b, CMPEqual<int>()))
{ 
    // a==b
}

В этом примере не только типы не определены, так еще и действие, которое производится в функции equal_if, неизвестно пока не будет вызова этих функций.

UPD: Обновление для того, чтобы минимизировать упоминание типов. В примере выше передается параметром CMPEqual<int>(), спрашивается зачем указывать тип явно, если его можно вывести неявно из типа переменных a и b. Вот как это можно сделать:

Меняем функцию сравнения:

template<template<class> class CMP, class T>
bool equal_if(T a, T b)
{
    return CMP<T>()(a,b);
}

Вызов меняется так, что явно типы указываются только при создании переменных:

int a=2, b=3;
if (equal_if<CMPLess>(a, b))
{ 
    // a<b
}
▲ 2

Вариантов два.

1) перегрузка функций. Это означает, что мы делаем N функций с одним и тем же именем, но разными типами входных данных. Но при этом нужно быть внимательным. Т.е. так сделать можно, но череповато:

char add(char,char);
int add(int,int);
double add(double,double);

//... где-то в коде
int x=10, y=0;
std::cout<<x<<"+"<<y<<add((double)x,y);
// так какой же вариант ф-ции выбрать!?
// а так работает:
std::cout<<x<<"+"<<y<<add((double)x,(double)y);

2) использование шаблонов. Шаблоны это очень занятно. По факту шаблон разворачивается в реальный код по месту использования его в коде. Поэтому код пухнет, но зато обеспечивается гибкость.