21

Re: Не працює шаблон

Радше fill_from.

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

22

Re: Не працює шаблон

koala написав:

Радше fill_from.

Або так )

23

Re: Не працює шаблон

Ото я вам знайшов тему порозмовляти ))
Я ж ще далі вчу цю осучаснену за роки мову, тому не все ще знайшов, хоча вже не мало я думаю. Просто вчити треба з прикладами застосування. От я собі і знайшов завдання де багато можна обкатати. А ту стандартну фью я мабуть і не бачив, тому і не копіював. Якщо щось не знайшов, роблю своє. Намагаюсь робити якомога універсальніше. В мене вже все давно нормально працює. Це я просто вкотре перепроходжу, оптимізую код.
А чому С++? Бо це класика, з якої поки що треба починати. Все що я бачу далі: Go, Swift не далеко пішли і від деяких ідей там я не в захваті. Я думаю що треба взагалі поміняти і концепцію і синтаксис операторів, зробити реверс вказівнику, можна і transform з bind поєднати в одному операторі і багато шо ще. Цей інструментарій в принципі застарів, але має багато напрацювань. Тільки не треба ліпити просто швидше аби щось своє як це сьогодні відбувається. Що буде  в голові років через 20 після постійних переробок і адаптації до вічно нового. Але очей, ніг, рук все ще по два, ми чомусь не мутуємо так швидко. Тому і програмний інструментарій має розвиватись поетапно, а не як дріжджі кинули в лайно. Фірм трильйонщіків вже декілька і всі хто як хоче, так і ... А зробити щось спільне продумане все ніяк не дійде до них. Мабуть поки людство не освідомить що капіталізм, це просто ще одна ступеня до самоорганізації і відповідальності далі справжніх рухів не буде. Тільки кіпіш і контраст гаманців як сьогодні.

24

Re: Не працює шаблон

Та вам уже сказали: дивіться в бік Rust, це майбутнє.
Ну і ідея центрального планування, знаєте, не нова. І закінчується це голодомором і ГУЛАГом, без винятків.

25 Востаннє редагувалося koala (29.01.2020 11:56:13)

Re: Не працює шаблон

В тему.

void print(int x) { std::cout<<"Integer="<<x; }
void print(std::string s) { std::cout<<"String="<<s; }
...
std::vector<int> vector_int = {1,2,3,4,5};
std::vector<std::string> vector_string = {"Lorem","ipsum","dolor","sit","amet"};
std::for_each(vector_int.begin(),vector_int.end(),print);//<<Як змусити це працювати?

Є щось простіше за

std::for_each(vector_int.begin(),vector_int.end(),[&](auto x){print(x);});

?

26 Востаннє редагувалося wander (29.01.2020 12:21:38)

Re: Не працює шаблон

koala написав:

Є щось простіше за

Загалом це самий простий варіант)
Можна явно допомагати компілятору, проте це явно не те чого ви хочете:

std::for_each(vector_int.begin(),vector_int.end(), (void(*)(int))print);

:)
Проблема в тому, що в цьому контексті перевантаження не можуть бути розрішені компілятором.
std::for_each - очікує деякого довільного типу F (функтора), а не якогось конкретного типу функції, тому перевантаження неоднозначні.

Можна зробити красивіше та зручніше для використання, але не для написання:

#define RETURNS(...) noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
#define LIFT(fn) [](auto&&... args) RETURNS(fn(::std::forward<decltype(args)>(args)...))

void print(int x) { std::cout<<"Integer="<<x; }
void print(std::string s) { std::cout<<"String="<<s; }

int main() {
    std::vector<int> vector_int = {1,2,3,4,5};
    std::vector<std::string> vector_string = {"Lorem","ipsum","dolor","sit","amet"};
    std::for_each(vector_int.begin(),vector_int.end(), LIFT(print));
}

:)

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

27

Re: Не працює шаблон

Вітаю, чи не могли б ви допомогти і з моєю проблемою?

У мене є деякий std::tuple і я хотів би перевірити чи елементи тапла можна між собою додати?
Я розумію, що це можна якось зробити через шаблони, але не можу цього склеїти докупи в себе в голові, щоб реалізувати.

28 Востаннє редагувалося wander (29.01.2020 15:03:10)

Re: Не працює шаблон

mimik написав:

Вітаю, чи не могли б ви допомогти і з моєю проблемою?

У мене є деякий std::tuple і я хотів би перевірити чи елементи тапла можна між собою додати?
Я розумію, що це можна якось зробити через шаблони, але не можу цього склеїти докупи в себе в голові, щоб реалізувати.

Як варіант, можна ось так:

#include <tuple>
#include <iostream>
#include <string>

template <typename... Ts>
constexpr auto check_impl(...) noexcept -> bool { return false; }

template <typename... Ts>
constexpr auto check_impl(int) noexcept -> decltype((std::declval<Ts>() + ...), bool{}) {
    return true;
}

template <typename... Ts>
constexpr bool check(std::tuple<Ts...>) noexcept {
    return check_impl<Ts...>(0);
}

int main() {
    std::cout << check(std::tuple<int, double, char>{}) << ' ' << check(std::tuple<int, std::string>{});
}

Але необхідна підтримка С++17 інакше, тре буде переписувати :)

Подякували: mimik, 0x9111A, leofun013

29

Re: Не працює шаблон

Так, дякую, все працює. А можете ще пояснити чому це працює? Раніше ні разу такого синтаксису не бачив
constexpr auto check_impl(int) noexcept -> decltype((std::declval<Ts>() + ...), bool{})

30 Востаннє редагувалося wander (29.01.2020 17:46:15)

Re: Не працює шаблон

mimik написав:

Так, дякую, все працює. А можете ще пояснити чому це працює? Раніше ні разу такого синтаксису не бачив
constexpr auto check_impl(int) noexcept -> decltype((std::declval<Ts>() + ...), bool{})

Що саме пояснити? Взагалі все? Я ж не знаю вашого рівня..
Ну, тим не менш, зробимо ось так:

constexpr auto check_impl(int) noexcept -> decltype((std::declval<Ts>() + ...), bool{})

Можете поклацати по специфікаторах та почитати про кожен з них окремо.
Три основні рушії на яких тримається вся ідея це:
1) Fold expression ( pack op ... ), які приїхали до нас у С++17;
2) Substitution Failure Is Not An Error (SFINAE);
3) Comma operator. Нам необхідна його основна властивість - це групування зліва направо, тобто відкиданням лівого виразу і залишенням результату лише правого. Таким чином під лівим виразом у нас знаходиться fold expression `(std::declval<Ts>() + ...)`, який розкривається та намагається додати всі елементи з набору, якщо все проходить успішно, то ми цей вираз вже відкидаємо, та результатом ф-ї виводимо тип bool, якщо ж йому це не вдається - отримуємо помилку, та по SFINAE попадаємо у другу перегружену ф-ю:

template <typename... Ts>
constexpr auto check_impl(...) noexcept -> bool { return false; }

, яка просто повертає false. Це означає, що нам не вдалося додати всі елементи.

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

Подякували: 0x9111A, mimik, koala, leofun014

31

Re: Не працює шаблон

adziri, ого, дякую вам за настільки детальний розпис. Обов'язково ще почитаю про всі специфікатори.

Подякували: wander, koala2