Тема: У циклі або рекурсивно вивести вміст tuple.
Якщо маємо
auto t = make_tuple(1, 3, 5.3, 't', "sdfasfd");
Як у циклі або рекурсивно вивести її в cout.
Мій варіант:
Ви не увійшли. Будь ласка, увійдіть або зареєструйтесь.
Ласкаво просимо вас на україномовний форум з програмування, веб-дизайну, SEO та всього пов'язаного з інтернетом та комп'ютерами.
Будемо вдячні, якщо ви поділитись посиланням на Replace.org.ua на інших ресурсах.
Для того щоб створювати теми та надсилати повідомлення вам потрібно Зареєструватись.
Український форум програмістів → C++ → У циклі або рекурсивно вивести вміст tuple.
Сторінки 1
Для відправлення відповіді ви повинні увійти або зареєструватися
Якщо маємо
auto t = make_tuple(1, 3, 5.3, 't', "sdfasfd");
Як у циклі або рекурсивно вивести її в cout.
Мій варіант:
Обхід кортежу виглядає як збочення, що в циклі, що рекурсивно.
Обхід кортежу виглядає як збочення, що в циклі, що рекурсивно.
Під час зневадження іноді потрібно
Чому тоді не виводити поелементно? Що там у вас за кортежі такі?
Чому тоді не виводити поелементно? Що там у вас за кортежі такі?
Чуєш легеньочку, або пиши відповідь, або котись під три чорти! >:o
Це рекурсивнозалуплений код на вас так подіяв?
quez написав:Чому тоді не виводити поелементно? Що там у вас за кортежі такі?
Чуєш легеньочку, або пиши відповідь, або котись під три чорти! >:o
Отаким відповідати точно не хочу.
Якщо маємо
auto t = make_tuple(1, 3, 5.3, 't', "sdfasfd");
Як у циклі або рекурсивно вивести її в cout.
Мій варіант:
▼Прихований текст
За такий код треба гнати під три чорти. І іншим заборонити згадувати.
За такий код треба гнати під три чорти. І іншим заборонити згадувати.
Конструктивненько...
Ви в стані написати кращий? Чи хоча б вказати на вади цього?
Ваш код - це приклад того, як можна відносно просту задачу вирішити таким "ажурним" способом, що сам автор не може збагнути, як це все функціонує.
Добра практика - це коли відносно складну задачу вирішують відносно простим способом.
А Ваш код - для тих, кому свербить спробувати гвіздка забити не за допомогою молотка, а використати щойно придбаний пристрій. Він, правда, зовсім для інших цілей зроблений, але зараз треба забити гвіздок, і під рукою як раз цей чудо-пристрій. Хто може зробити краще?
Програмоїдів з такими замашками - закреслити раз і назавжди!
Все ж хотілось би почути критику коду окремо від критики манери ведення дискусії автора цього коду. У чому його неймовірна складність — також не помітив.
Я знаю С++ не настільки глибоко, щоб бачити явні недоліки. А втім, елементом кортежа також може бути кортеж (який сам по собі не годиться для виводу)? Тоді такий спосіб не спрацює...
Наприклад, перевизначення оператора () для непритаманної йому операції.
Наприклад, перевизначення оператора () для непритаманної йому операції.
А які операції притаманні оператору () ?
Щоб не затягувати обговорення додам, що це просто функтор, він може робити будь-що.
Все ж хотілось би почути критику коду окремо від критики манери ведення дискусії автора цього коду. У чому його неймовірна складність — також не помітив.
Я знаю С++ не настільки глибоко, щоб бачити явні недоліки. А втім, елементом кортежа також може бути кортеж (який сам по собі не годиться для виводу)? Тоді такий спосіб не спрацює...
Можна перевантажити operator<< для кортежу:
#include <iostream>
#include <tuple>
#include <type_traits>
using namespace std;
template<size_t Size, typename... Args>
typename enable_if<Size == 0, void>::type tuple_print_hlp(ostream& ostr, const tuple<Args...>& t)
{}
template<size_t Size, typename... Args>
typename enable_if<(Size > 0), void>::type tuple_print_hlp(ostream& ostr, const tuple<Args...>& t)
{
tuple_print_hlp<Size - 1>(ostr, t);
cout << get<Size - 1>(t) << endl;
}
template<size_t Size, typename... Args>
typename enable_if<Size == 0, void>::type tuple_print(ostream& ostr, const tuple<Args...>& t)
{}
template<size_t Size, typename... Args>
typename enable_if<(Size > 0), void>::type tuple_print(ostream& ostr, const tuple<Args...>& t)
{
tuple_print_hlp<Size - 1>(ostr, t);
cout << get<Size - 1>(t); // Останній елемент виводимо саме тут для того, щоб не виводити зайвого endl
}
template<typename... Args>
ostream& operator<<(ostream& ostr, const tuple<Args...>& t)
{
tuple_print<tuple_size<tuple<Args...> >::value>(ostr, t);
return ostr;
}
int main(void)
{
auto t = make_tuple(1, 3, make_tuple(5.3, "gtewtg"), 't', make_tuple("sdfasfd", 234, 56.75));
cout << t << endl;
return 0;
}
Трюк з індексами плюс розширення пакована шаблонних параметрів.
//фактично оце
f(h(args)...);
//розширюється до цього
f(h(E1), h(E2), h(E3), ...)
// E1..En - аргументи у варіадичному шаблоні
ось іще
f(h(args...) + args...);
f(h(E1,E2,E3) + E1, h(E1,E2,E3) + E2, h(E1,E2,E3) + E3)
І сам жахастик
// **********************************************************************************************
template <size_t... Is>
struct indices {};
template <size_t N, size_t... Is>
struct build_indices : build_indices<N - 1, N - 1, Is...> {};
template <size_t... Is>
struct build_indices<0, Is...> : indices<Is...>{};
template <typename Tuple>
using IndicesFor = build_indices<tuple_size<Tuple>::value>;
// **********************************************************************************************
template <typename T>
struct is_tuple : false_type {};
template <typename... T>
struct is_tuple<tuple<T...>> : true_type{};
// **********************************************************************************************
// Порожня
void printImpl(char) {}
template <typename Tuple, typename ..._Vals,
typename enable_if<is_tuple<typename decay<Tuple>::type>::value>::type* = nullptr> //SFINAE
void printImpl(int, Tuple&& t, _Vals... _vals)
{
print_tuple(forward<typename decay<Tuple>::type>(t));
after_print(_vals...);
}
template <typename _First, typename ..._Vals>
void printImpl(char, _First&& first, _Vals... _vals)
{
cout << first;
after_print(_vals...);
}
// **********************************************************************************************
template <typename ..._Vals>
void after_print(_Vals... _vals)
{
cout << " ";
printImpl(0, _vals...);
}
void after_print() {}
// **********************************************************************************************
template <typename T, size_t... Is>
void print_tuple2(T&& t, indices<Is...>)
{
// 0 ближче до int ніж до char
printImpl(0, get<Is>(forward<T>(t))...);
}
// **********************************************************************************************
template <typename T>
void print_tuple(T&& t)
{
cout << "{";
print_tuple2(forward<T>(t), IndicesFor<T> {});
cout << "}";
}
// **********************************************************************************************
// **********************************************************************************************
// rvalues
print_tuple(make_tuple(make_tuple(1, 2, "start_tuple"), 17, 'q', make_tuple("stop_tuple", 123)));
cout << endl;
// lvalue
int i = 0;
auto t = make_tuple();
print_tuple(make_tuple(i, t));
cout << endl;
Сторінки 1
Для відправлення відповіді ви повинні увійти або зареєструватися