Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Пример простой шаблонной функции


Автор: ZVano 11.3.2011, 17:05
Может кому пригодится, вот пример простой шаблонной функции InDiapason(val, side1, side2), которая проверяет находится ли значение val между side1 и side2.
Так выглядело без шаблона
Код

bool InDiapason_double(double val, double side1, double side2) {
    double sideMin = min<double>(side1, side2);
    double sideMax = max<double>(side1, side2);
    return val >= sideMin && val <= sideMax;
}

bool InDiapason_int(int val, int side1, int side2) {
    int sideMin = min<int>(side1, side2);
    int sideMax = max<int>(side1, side2);
    return val >= sideMin && val <= sideMax;
}

Это не есть хорошо - плодить функции, делающие одно и тоже, но различающиеся типом данных на входе.

Поэтому пишем шаблон.
Код

template<class T>
bool InDiapason(T val, T side1, T side2) {
    T sideMin = min<T>(side1, side2);
    T sideMax = max<T>(side1, side2);
    return val >= sideMin && val <= sideMax;
}

//а еще лучше, так:
template<class T>
bool InDiapason(T val, T side1, T side2) {
    return val >= min<T>(side1, side2) && val <= max<T>(side1, side2);
}



Используем так:
Код

    int val = 1, side1 = 3, side2 = 5;

    if (InDiapason(val, side1, side2)) {
        ShowMessage("В диапазоне");
    }
    else {
        ShowMessage("Не в диапазоне");
    }

Автор: mes 11.3.2011, 17:31
Цитата(ZVano @  11.3.2011,  16:05 Найти цитируемый пост)
   T sideMin = min<T>(side1, side2);
    T sideMax = max<T>(side1, side2);
    return val >= sideMin && val <= sideMax;


имхо локальные переменные только загромождают код в данном случае..
Код

return val >= min<T>(side1, side2)
    && val <= max<T>(side1, side2);


а вообще, мне кажется вместо функции, лучше создать класс диапазон с нужными методами..

Автор: bsa 11.3.2011, 17:35
К сожалению, предложенный способ использования не очень удобен. А удобный работать не будет:
Код
double x = 10;
if (InDiapason(x, 1, 20))
   std::cout << "OK" << std::endl;

Автор: ZVano 11.3.2011, 17:41
Цитата(mes @  11.3.2011,  17:31 Найти цитируемый пост)
имхо локальные переменные только загромождают код в данном случае..

Спасибо, исправил в шапке.

Автор: mes 11.3.2011, 18:57
Цитата(bsa @  11.3.2011,  16:35 Найти цитируемый пост)
К сожалению, предложенный способ использования не очень удобен. А удобный работать не будет:

легким движением руки брюки превращаются ©

Код

template<typename A, typename T>
bool InDiapason(A const& val, T const& a1, T const& a2) {
    return val >= std::min(a1, a2) 
        && val <= std::max(a1, a2);
}

int main() {
   double x = 10;
   if (InDiapason(x, 1, 20))
      std::cout << "OK" << std::endl;
}


http://liveworkspace.org/code/8e55dd1474e745178d8a9a75a287290d
smile 

Автор: mes 11.3.2011, 20:15
Цитата(mes @  11.3.2011,  16:31 Найти цитируемый пост)
класс диапазон

вот пример :
http://liveworkspace.org/code/ac80857007beb8998f69efc985a2ecd6

и альтернативный вариант, на мой взгляд более приемлемый, где contain не является членом класса range :
http://liveworkspace.org/code/8525efa23c8890e680a090e682a98079

ну и в продолжение, с добавлением перегрузки функции для удобства :
http://liveworkspace.org/code/add387a49fc973d4f1ba3f7eba7186ae

Автор: ZVano 11.3.2011, 20:31
Цитата(mes @  11.3.2011,  20:15 Найти цитируемый пост)
вот пример :http://liveworkspace.org/code/ac80857007be...f69efc985a2ecd6

Спасибо. Пока непонятно, но работает. Буду грызть гранит дальше.

Автор: mes 11.3.2011, 20:49
Цитата(ZVano @  11.3.2011,  19:31 Найти цитируемый пост)
Пока непонятно

auto непонятна ? 
можно заменить 
Цитата

Код

 auto _range =  make_range(1, 20);


на
Код

 range<int> _range(1, 20);

или вместо 
Цитата

Код

   auto _range =  make_range(1, 20);   
   if (_range.contain(4.5))


сразу писать
Код

 if (make_range(1, 20).contain(4.5))

Автор: borisbn 28.4.2011, 15:46
Цитата(mes @  11.3.2011,  18:57 Найти цитируемый пост)
    
return val >= std::min(a1, a2)         
    && val <= std::max(a1, a2);

а может лучше заставить пользователя определить только одну операцию вместо двух ? например только >=
Код

return val >= std::min(a1, a2)         
     && std::max(a1, a2) >= val;

Автор: mes 28.4.2011, 15:52
Цитата(borisbn @  28.4.2011,  14:46 Найти цитируемый пост)
а может лучше заставить пользователя определить только одну операцию вместо двух ? например только >=

тогда уж следовать общепринятой тенденции и оставить одну операцию меньше smile

Автор: borisbn 28.4.2011, 16:36
Цитата(mes @  28.4.2011,  15:52 Найти цитируемый пост)
тогда уж следовать общепринятой тенденции и оставить одну операцию меньше 

Не имею желания, а также сообщаю об отсутствии тенденции делать вещь в высшей степени глупую, а именно - возражать. Другими словами имею желание сделать сообщение, что согласен на все 0x64  smile 

Автор: asmdzen 28.4.2011, 17:04
как пример из шапки превратить в inline?

Автор: mes 28.4.2011, 20:31
Цитата(borisbn @  28.4.2011,  15:36 Найти цитируемый пост)
Не имею желания, а также сообщаю об отсутствии тенденции делать вещь в высшей степени глупую, а именно - возражать. Другими словами имею желание сделать сообщение, что согласен на все 0x64

 smile  smile  smile 

пример для оператора < 
Код

template<typename T, typename A>
bool contain (A const& a, range<T> const& range)
{
   return !(a < range.begin || range.end < a) ;
}


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)