Re: Не працює шаблон
Радше fill_from.
Ви не увійшли. Будь ласка, увійдіть або зареєструйтесь.
Ласкаво просимо вас на україномовний форум з програмування, веб-дизайну, SEO та всього пов'язаного з інтернетом та комп'ютерами.
Будемо вдячні, якщо ви поділитись посиланням на Replace.org.ua на інших ресурсах.
Для того щоб створювати теми та надсилати повідомлення вам потрібно Зареєструватись.
Український форум програмістів → C++ → Не працює шаблон
Для відправлення відповіді ви повинні увійти або зареєструватися
Ото я вам знайшов тему порозмовляти ))
Я ж ще далі вчу цю осучаснену за роки мову, тому не все ще знайшов, хоча вже не мало я думаю. Просто вчити треба з прикладами застосування. От я собі і знайшов завдання де багато можна обкатати. А ту стандартну фью я мабуть і не бачив, тому і не копіював. Якщо щось не знайшов, роблю своє. Намагаюсь робити якомога універсальніше. В мене вже все давно нормально працює. Це я просто вкотре перепроходжу, оптимізую код.
А чому С++? Бо це класика, з якої поки що треба починати. Все що я бачу далі: Go, Swift не далеко пішли і від деяких ідей там я не в захваті. Я думаю що треба взагалі поміняти і концепцію і синтаксис операторів, зробити реверс вказівнику, можна і transform з bind поєднати в одному операторі і багато шо ще. Цей інструментарій в принципі застарів, але має багато напрацювань. Тільки не треба ліпити просто швидше аби щось своє як це сьогодні відбувається. Що буде в голові років через 20 після постійних переробок і адаптації до вічно нового. Але очей, ніг, рук все ще по два, ми чомусь не мутуємо так швидко. Тому і програмний інструментарій має розвиватись поетапно, а не як дріжджі кинули в лайно. Фірм трильйонщіків вже декілька і всі хто як хоче, так і ... А зробити щось спільне продумане все ніяк не дійде до них. Мабуть поки людство не освідомить що капіталізм, це просто ще одна ступеня до самоорганізації і відповідальності далі справжніх рухів не буде. Тільки кіпіш і контраст гаманців як сьогодні.
Та вам уже сказали: дивіться в бік Rust, це майбутнє.
Ну і ідея центрального планування, знаєте, не нова. І закінчується це голодомором і ГУЛАГом, без винятків.
В тему.
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);});
?
Є щось простіше за
Загалом це самий простий варіант)
Можна явно допомагати компілятору, проте це явно не те чого ви хочете:
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));
}
Вітаю, чи не могли б ви допомогти і з моєю проблемою?
У мене є деякий std::tuple і я хотів би перевірити чи елементи тапла можна між собою додати?
Я розумію, що це можна якось зробити через шаблони, але не можу цього склеїти докупи в себе в голові, щоб реалізувати.
Вітаю, чи не могли б ви допомогти і з моєю проблемою?
У мене є деякий 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 інакше, тре буде переписувати
Так, дякую, все працює. А можете ще пояснити чому це працює? Раніше ні разу такого синтаксису не бачив
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. Це означає, що нам не вдалося додати всі елементи.
Виникає логічне питання: чому ми спочатку попадему в одну, а лише потім в іншу ф-ї?
Все завдяки еліпсису, який має найнижчий пріоритет по вибору підходящої ф-ї підчас розрішення вибору перегружених ф-й. Тобто компілятор спочатку буде намагатися підібрати будь-яку іншу ф-ю і лиш потім вибере ф-ю з еліпсисом.
Для відправлення відповіді ви повинні увійти або зареєструватися