1 Востаннє редагувалося koala (20.07.2021 16:18:46)

Тема: Перевантаження функції, повторення коду.

Привіт, недавно вернувся до вивчення С++ :D
Так ось...
Перевантаження функцій...
Ось код

Code
int max(int num1, int num2)
{
    if (num1 > num2)
    {
        return num1;
    }

    else
    {
        return num2;
    }
}

double max(double num1, double num2)
{
    if (num1 > num2)
    {
        return num1;
    }

    else
    {
        return num2;
    }
}

int main()
{
    int imax = max(1, 10);
    double dmax = max(1.0, 20.0);
    return 0;
}

Чи можливо уникнути повторювання коду в даній ситуації :D?
І так, я знаю про оце:

Code
auto max(auto num1, auto num2)
{
    if (num1 > num2)
    {
        return num1;
    }

    else
    {
        return num2;
    }
}

int main()
{
    int imax = max(1, 10);
    double dmax = max(1.0, 20.0);
    return 0;
}

Але, чи можна якось обійтись без цього auto ?

2

Re: Перевантаження функції, повторення коду.

Кури темплейти в С++. Для цієї мети воно саме те, що треба.

Подякували: koala, mamkin haker, leofun01, dot4

3

Re: Перевантаження функції, повторення коду.

Олд скул. Мова C, можна і в плюсах (не рекомендовано):

#define max(a,b) (((a)>(b))?(a):(b))

Проблеми: якщо має повертати значення - обмеження одним виразом, жодного контролю типів, подвійне обчислення аргументів, наприклад, max(a++, b++) збільшить більше число на два.
C++ до C++20:

template<typename T>
T max(T a, T b)
{
  if(a>b)
    return a;
  else
    return b;
}

C++20 надає скорочену форму попереднього виразу через auto:

auto max(auto a, auto b)
{
  if(a>b)
    return a;
  else
    return b;
}

означає абсолютно те саме, що й попередній код.
Так, а тепер ще раз: чому ви хочете "обійтись без цього auto"?

Подякували: leofun011

4

Re: Перевантаження функції, повторення коду.

koala написав:

C++ до C++20:

template<typename T>
T max(T a, T b) { /* ... */ }

C++20 надає скорочену форму попереднього виразу через auto:

auto max(auto a, auto b) { /* ... */ }

означає абсолютно те саме, що й попередній код.

Наче все так, але є відмінність.

Такий код

auto max(auto a, auto b) { /* ... */ }

скоріше еквівалентний такому

template<typename T1, typename T2, typename T3>
T3 max(T1 a, T2 b) { /* ... */ }

що дозволяє викориcтати його з різними типами

double d = max((int)1, (float)0.1);

А в такому темплейті

template<typename T>
T max(T a, T b) { /* ... */ }

Аргументи будуть приведені до одного типу (якщо це можливо) і результат того самого типу.

Тож іноді є сенс не використовувати auto.

Подякували: /KIT\, ch0r_t, koala, dot4

5

Re: Перевантаження функції, повторення коду.

Загалом так, але конкретно в цьому випадку a та b мають бути одного типу, інакше return a та return b не дозволяють компілятору визначити, який тип повертає функція.

Подякували: leofun011

6

Re: Перевантаження функції, повторення коду.

Дякую :3 дуже цікаві штуки показуєте

koala написав:

Олд скул. Мова C, можна і в плюсах (не рекомендовано):

Тобто в С++ можна писати як і в С???
Взагалі все???
Тоді чи варто трішки зазирнути в світ С, може там є щось що ефективніше можна буде використовувати??

koala написав:

Так, а тепер ще раз: чому ви хочете "обійтись без цього auto"?

Якось недовіряю йому))
Параноя :D? Раніше його ж не було нібито =_=
C++ це ж з статичною типізацією, а тут auto, динамічне

дивно що такий код працює :D

#include <iostream>

int main()
{
    auto tests = 5;
    tests = 6.99;
    printf("%d\n", tests);
    return 0;
}

7

Re: Перевантаження функції, повторення коду.

По-перше, це інше auto - для визначення конкретного типу, а не узагальненого програмування.
По-друге, це статична типізація - просто тип визначається не прямо, а типом виразу, яким ініціалізується. І зроблено це все ж більше не для простих типів, а для конструкцій на кшталт

std::shared_ptr<std::vector<VeryLongClassName>> variable_name = std::make_shared<std::vector<VeryLongClassName>>(new std::vector<VeryLongClassName>());

щоб не повторюватися.
Можу вам сказати, що в так само статично типізованому Rust працює навіть таке:

let mut x; //let - аналог auto, mut - антонім const в C++
//якийсь код
if ... { x = 5; }
else {x = 8; }

Компілятор дивиться далі по коду, що робиться з x, і підставляє тип звідти.

Подякували: mamkin haker, leofun012

8

Re: Перевантаження функції, повторення коду.

mamkin haker написав:

дивно що такий код працює :D

#include <iostream>

int main()
{
    auto tests = 5;
    tests = 6.99;
    printf("%d\n", tests);
    return 0;
}

А ось такий

{
  char buff [50];
  auto next, one=15, two=3;
  next=sprintf (buff, "%d plus %d is %d", one, two, one+two);
  printf ("[%s] is a string %d chars long", buff, next);
  return 0;
}

вже дудки збереться

9 Востаннє редагувалося koala (20.07.2021 11:03:59)

Re: Перевантаження функції, повторення коду.

Droid 77 написав:

вже дудки збереться

Бо next неініціалізований, відповідно, його тип компілятору невідомий.
А от

auto next=0, one=15, two=3;

чи

auto one=15, two=3, next =sprintf (buff, "%d plus %d is %d", one, two, one+two);

вже чудово працюють.

10 Востаннє редагувалося Droid 77 (20.07.2021 12:49:01)

Re: Перевантаження функції, повторення коду.

Це якщо всі значення будуть цілі.
Спробуйте так само перетворити ось цю працездатну конструкцію:

  char buff [50];
  int next, one=15.2, two=3.3;
  next=sprintf (buff, "%d plus %d is %d", one, two, one+two);
  printf ("[%s] is a string %d chars long", buff, next);

З auto не пройде.
Я це до того, що з типом auto дуже легко заплутатись з літералами в коді.

11 Востаннє редагувалося koala (20.07.2021 13:12:02)

Re: Перевантаження функції, повторення коду.

Я б за таку ініціалізацію бив. Так, C++ схаває (на відміну від, скажімо, того ж Rust), але який ідіот буде пхати double в int при ініціалізації? От що, від того, що значення будуть цілими, хтось помре? Релігія забороняє самому округлювати?

12 Востаннє редагувалося Droid 77 (20.07.2021 14:24:05)

Re: Перевантаження функції, повторення коду.

Та ось Вам живий приклад.
Отримувати значення з сенсора в поточному часі. Вивести цілочисельне значення на дисплей.
Спрощений приклад:

char buff [50];
  int next, sens, two=3;
  sens=15.2; // Sensor literal, value changes over time. Limit to integer value.
  next=sprintf (buff, "%d plus %d is %d", sens, two, sens+two);
  printf ("[%s] is a string %d chars long", buff, next);

P. S.
Наприклад two=3 — корегування похибки сенсора.

13

Re: Перевантаження функції, повторення коду.

Droid 77 написав:

Отримувати значення з сенсора в поточному часі.

Літералом? У поточному часі? Оригінально. Що, прямо в поточному часі підставляти літерал у код, компілювати і запускати, щоб виводив?

14

Re: Перевантаження функції, повторення коду.

То спрощений приклад для пояснення висловлювання

koala написав:

який ідіот буде пхати double в int при ініціалізації? От що, від того, що значення будуть цілими, хтось помре? Релігія забороняє самому округлювати?

та де взагалі таке може бути використано.
В реальному часі той літерал береться безпосередньо з сенсора.
Та і загальний код беде геть інший.

15

Re: Перевантаження функції, повторення коду.

Droid 77 написав:

Я це до того, що з типом auto дуже легко заплутатись з літералами в коді.

Якщо писати лайнокод, то заплутатись можна і без auto.

Подякували: koala1

16

Re: Перевантаження функції, повторення коду.

Тю на Вас..

17

Re: Перевантаження функції, повторення коду.

Від модератора: виправив термінологію в першому повідомленні

18

Re: Перевантаження функції, повторення коду.

koala написав:

Від модератора: виправив термінологію в першому повідомленні

?_?
А можна мені теж право редагувати свої повідомлення?
?_?
Заздалегідь дякую!

19 Востаннє редагувалося Droid 77 (20.07.2021 19:00:57)

Re: Перевантаження функції, повторення коду.

Це, мабуть, спрацював пункт 1.4 правил форума з якими Ви заздалегідь погодилися )

20

Re: Перевантаження функції, повторення коду.

Droid 77 написав:

Це, мабуть, спрацював пункт 1.4 правил форума з якими Ви заздалегідь погодилися )

Та я про те спитав чи можна мені такі права видати на редагування своїх повідомлень :3

кулсторі?

В 2012 році коли грав майнкрафт були сервери (да ну, правда?)
Так ось, донатних адміністраторів і модераторів тоді ще не було.
І якщо хтось з звичайних гравців вирішував облаяти* сервер або адміністрацію то його слали зразу в бан.

Ну, я сижу на цьому форумі, тут є правила, і я їх прийняв і прочитав коли реєструвався.
Тому я нічого не маю проти того що моє повідомлення відредаговано, тим більше що там якісь помилки були та пан koala їх виправив :3


Прихований текст

автору 10 років і айсикю в нього як у буханця хліба :D