Выражения свёртки без дополнительной функции
От: _NN_ www.nemerleweb.com
Дата: 18.04.19 11:55
Оценка:
template<typename T>
void pack(T const& value) { ... }

// Вариант 1 через дополнительную функцию и выражения свёртки
template <typename Tuple, std::size_t... Is>
void pack_impl(Tuple const& tup, std::index_sequence<Is...>)
{
    (pack(std::get<Is>(tup)), ...);
}

template<template<typename... Ts> class Tuple, typename... Types>
void pack1(Tuple<Types...> const& tup)
{
    pack_impl(tup, std::index_sequence_for<Types...>{});
}

// Вариант 2 через std::apply
template<template<typename... Ts> class Tuple, typename... Types>
void pack2(Tuple<Types...> const& tup)
{
    std::apply([](auto && ... args) { (pack(std::forward<decltype(args)>(args)), ...); }, tup);
}

int main()
{
    int arr[] = { 1,2,3 };
    pack(std::tie(arr));
}


Как можно улучшить этот код ?
Хотелось бы иметь возможность раскрыть tuple по месту без дополнительной функции.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Выражения свёртки без дополнительной функции
От: niXman Ниоткуда https://github.com/niXman
Дата: 18.04.19 12:03
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Хотелось бы иметь возможность раскрыть tuple по месту без дополнительной функции.


поясни.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: Выражения свёртки без дополнительной функции
От: _NN_ www.nemerleweb.com
Дата: 18.04.19 13:19
Оценка:
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, _NN_, Вы писали:


_NN>>Хотелось бы иметь возможность раскрыть tuple по месту без дополнительной функции.


X>поясни.


Вместо
 std::apply([](auto && ... args) { (pack(std::forward<decltype(args)>(args)), ...); }, tup);


Хочется что-то вроде:
(pack(tup...), ...)


Которое бы раскрывалось в
(pack(get<0>(tup)), pack(get<1>(tup), ... pack(get<size(tup)>(tup));
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Выражения свёртки без дополнительной функции
От: reversecode google
Дата: 18.04.19 14:18
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>
_NN>template<typename T>
_NN>void pack(T const& value) { ... }

удаляем
_NN>// Вариант 1 через дополнительную функцию и выражения свёртки
_NN>template <typename Tuple, std::size_t... Is>
_NN>void pack_impl(Tuple const& tup, std::index_sequence<Is...>)
_NN>{
_NN>    (pack(std::get<Is>(tup)), ...);
_NN>}

меняем боди на
for_all([](auto&& tup) {
        //////???????
      }, std::get<Is>(tup)...);


_NN>template<template<typename... Ts> class Tuple, typename... Types>
_NN>void pack1(Tuple<Types...> const& tup)
_NN>{
_NN>    pack_impl(tup, std::index_sequence_for<Types...>{});
_NN>}

_NN>// Вариант 2 через std::apply
_NN>template<template<typename... Ts> class Tuple, typename... Types>
_NN>void pack2(Tuple<Types...> const& tup)
_NN>{
_NN>    std::apply([](auto && ... args) { (pack(std::forward<decltype(args)>(args)), ...); }, tup);
_NN>}

_NN>int main()
_NN>{
_NN>    int arr[] = { 1,2,3 };
_NN>    pack(std::tie(arr));
_NN>}
_NN>


_NN>Как можно улучшить этот код ?

_NN>Хотелось бы иметь возможность раскрыть tuple по месту без дополнительной функции.
Отредактировано 18.04.2019 14:20 reversecode . Предыдущая версия .
Re[2]: Выражения свёртки без дополнительной функции
От: _NN_ www.nemerleweb.com
Дата: 18.04.19 15:37
Оценка:
Здравствуйте, reversecode, Вы писали:

R>Здравствуйте, _NN_, Вы писали:


_NN>>
_NN>>template<typename T>
_NN>>void pack(T const& value) { ... }
R>

R>удаляем
R>
_NN>>// Вариант 1 через дополнительную функцию и выражения свёртки
_NN>>template <typename Tuple, std::size_t... Is>
_NN>>void pack_impl(Tuple const& tup, std::index_sequence<Is...>)
_NN>>{
_NN>>    (pack(std::get<Is>(tup)), ...);
_NN>>}
R>

R>меняем боди на
R>
R>for_all([](auto&& tup) {
R>        //////???????
R>      }, std::get<Is>(tup)...);
R>


Чем это лучше ?
И что такое for_all ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Выражения свёртки без дополнительной функции
От: rg45 СССР  
Дата: 18.04.19 17:05
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Вместо

_NN>
 std::apply([](auto && ... args) { (pack(std::forward<decltype(args)>(args)), ...); }, tup);


_NN>Хочется что-то вроде:

_NN>
(pack(tup...), ...)


std::initializer_list<int> { (pack(tup...), 0)... };


Оно?
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 18.04.2019 17:05 rg45 . Предыдущая версия .
Re[4]: Выражения свёртки без дополнительной функции
От: _NN_ www.nemerleweb.com
Дата: 18.04.19 17:11
Оценка:
Здравствуйте, rg45, Вы писали:

_NN>>Хочется что-то вроде:

_NN>>
(pack(tup...), ...)


R>
R>std::initializer_list<int> { (pack(tup...), 0)... };
R>


R>Оно?

Оно если бы компилятор умел из tup... делать get<0>(tup), get<1>(tup)...
А так не будет собираться, ведь я передаю один аргумент Tuple<Types...>.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Выражения свёртки без дополнительной функции
От: ViTech  
Дата: 19.04.19 09:31
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Хочется что-то вроде:

_NN>
(pack(tup...), ...)


_NN>Которое бы раскрывалось в

_NN>
(pack(get<0>(tup)), pack(get<1>(tup), ... pack(get<size(tup)>(tup));


Fold expressions работают с parameter pack. tuple — это не parameter pack, соответственно fold expressions не с чем работать, и в текущих реалиях C++ придётся привлечь дополнительную функцию для "раскрытия" tuple.

_NN>Вместо

_NN>
 std::apply([](auto && ... args) { (pack(std::forward<decltype(args)>(args)), ...); }, tup);


На основе этой строки можно написать функцию типа apply_elements(pack, tup). Вроде выглядит не хуже, чем (pack(tup...), ...).

Кстати, если среди элементов tup будут другие tuple(а в них ещё tuple и ещё и т.д.), они тоже должны раскрываться или обрабатываться в pack целиком?
Пока сам не сделаешь...
Re[5]: Выражения свёртки без дополнительной функции
От: rg45 СССР  
Дата: 19.04.19 12:41
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Оно если бы компилятор умел из tup... делать get<0>(tup), get<1>(tup)...

_NN>А так не будет собираться, ведь я передаю один аргумент Tuple<Types...>.

Как ни крути, где-то должен возникнуть контескт, в котором будет последовательность компайл тайм-индексов. И у тебя есть ровно две возможности: либо создать этот контескт самостоятельно (написать ту самую вспомогательную функцию), либо воспользоваться тем, что уже есть (apply). Вру, есть еще третья возмозность — использовать для доступа к элементам тупла типы вместо индексов. Но нормально работать это будет только в том случае, когда в тупле все типы разные.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 19.04.2019 17:18 rg45 . Предыдущая версия .
Re[4]: Выражения свёртки без дополнительной функции
От: rg45 СССР  
Дата: 20.04.19 06:17
Оценка:
Здравствуйте, ViTech, Вы писали:

_NN>>Хочется что-то вроде:

_NN>>
(pack(tup...), ...)


VT>Кстати, если среди элементов tup будут другие tuple(а в них ещё tuple и ещё и т.д.), они тоже должны раскрываться или обрабатываться в pack целиком?


Ну это уже зависит от устройства pack. Предоставив всего лишь одну перегрузку, иожно заставить вложенные туплы раскрываться в деревья.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[6]: Выражения свёртки без дополнительной функции
От: _NN_ www.nemerleweb.com
Дата: 20.04.19 06:58
Оценка:
Здравствуйте, rg45, Вы писали:

R>Как ни крути, где-то должен возникнуть контескт, в котором будет последовательность компайл тайм-индексов. И у тебя есть ровно две возможности: либо создать этот контескт самостоятельно (написать ту самую вспомогательную функцию), либо воспользоваться тем, что уже есть (apply). Вру, есть еще третья возмозность — использовать для доступа к элементам тупла типы вместо индексов. Но нормально работать это будет только в том случае, когда в тупле все типы разные.


Или добавить в язык возможность распаковки типов вроде tuple.
Выражение вроде "...a" раскрывать в:
get<0>(a), ... get<tuple_size<decltype(a)>::value>(a)


Тогда не нужен был бы std::apply.
Вместо

void f(int a, char c) {}

auto x = make_tuple(1, 'a');
apply(f, x);


Писать просто:
void f(int a, char c) {}

auto x = make_tuple(1, 'a');
f(...a);
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.