скопировать элементы тьюпла за исключением последнего
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.03.18 13:57
Оценка:
привет!

может кто уже писал аналогичный велосипед?
исключить первый — просто. а с последним что-то не получается...

нужно для std::tuple, в котором только константные ссылки. чтоб можно было использовать так: auto res = tuple_pop_back(src);

спасибо.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Отредактировано 20.03.2018 13:57 niXman . Предыдущая версия .
Re: скопировать элементы тьюпла за исключением последнего
От: watchmaker  
Дата: 20.03.18 14:17
Оценка: 9 (1) +1
Здравствуйте, niXman, Вы писали:

X>исключить первый — просто. а с последним что-то не получается...

А в чём разница, если к ним по индексам обращаться?

template <class T, size_t... I>
auto slice_tuple(const T& t, std::index_sequence<I...>) {
        return std::tuple<typename std::tuple_element<I, T>::type...>((std::get<I>(t))...);
}

template <class THead, class... TTail>
auto tuple_pop_back(const std::tuple<THead, TTail...>& t) {
    return slice_tuple(t, std::make_index_sequence<sizeof...(TTail)>());
}
Re[2]: скопировать элементы тьюпла за исключением последнего
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.03.18 14:19
Оценка:
Здравствуйте, watchmaker, Вы писали:

спасибо

W>А в чём разница, если к ним по индексам обращаться?

а до индексов я додумать не успел, пошел на форум
я начал думать про рекурсивное копирование и игнором последнего, но то что накодил сходу не заработало. %)
в общем — лень
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: скопировать элементы тьюпла за исключением последнего
От: vopl Россия  
Дата: 20.03.18 14:28
Оценка: +1
Здравствуйте, niXman, Вы писали:

X>привет!


X>может кто уже писал аналогичный велосипед?

X>исключить первый — просто. а с последним что-то не получается...

X>нужно для std::tuple, в котором только константные ссылки. чтоб можно было использовать так: auto res = tuple_pop_back(src);


X>спасибо.


начать можно отсюда http://en.cppreference.com/w/cpp/utility/make_from_tuple

и чуть переделать
#include <tuple>

namespace detail
{
    template <class Tuple, std::size_t... I>
    constexpr auto tuple_pop_back_impl( Tuple&& t, std::index_sequence<I...> )
    {
        return std::make_tuple(std::get<I>(std::forward<Tuple>(t))...);
    }
} // namespace detail
 
template <class Tuple>
constexpr auto tuple_pop_back( Tuple&& t )
{
    return detail::tuple_pop_back_impl(
        std::forward<Tuple>(t),
        std::make_index_sequence<std::tuple_size<std::remove_reference_t<Tuple>>::value-1>{});
}


int main()
{
    std::tuple<int, char> res = tuple_pop_back(std::make_tuple(220, '2', 3.14));
    return 0;
}
Re: скопировать элементы тьюпла за исключением последнего
От: Mr.Delphist  
Дата: 20.03.18 14:34
Оценка: :))
Здравствуйте, niXman, Вы писали:

X>исключить первый — просто. а с последним что-то не получается...


В традициях быстрых ответов на stackoverflow: сделать тупл с реверсным порядком элементов, удалить первый элемент, снова отревёрсить порядок элементов
Re[2]: скопировать элементы тьюпла за исключением последнего
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.03.18 14:35
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>В традициях быстрых ответов на stackoverflow: сделать тупл с реверсным порядком элементов, удалить первый элемент, снова отревёрсить порядок элементов

гении! я бы до этого не додумался =)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: скопировать элементы тьюпла за исключением последнего
От: Constructor  
Дата: 20.03.18 22:52
Оценка: +1
Здравствуйте, watchmaker, Вы писали:

W>
W>template <class T, size_t... I>
W>auto slice_tuple(const T& t, std::index_sequence<I...>) {
W>        return std::tuple<typename std::tuple_element<I, T>::type...>((std::get<I>(t))...);
W>}

W>template <class THead, class... TTail>
W>auto tuple_pop_back(const std::tuple<THead, TTail...>& t) {
W>    return slice_tuple(t, std::make_index_sequence<sizeof...(TTail)>());
W>}


В C++20 это можно будет запихнуть в одну функцию, воспользовавшись generic lambda со списком шаблонных параметров:

#include <tuple>
#include <utility>


template <typename... Elements>
constexpr auto tuple_pop_back(const std::tuple<Elements...>& tuple) noexcept
{
    static_assert(sizeof...(Elements) > 0, "'tuple_pop_back': 'tuple' must be a non-empty tuple.");

    return [&tuple]<std::size_t... indices>(std::index_sequence<indices...>)
    {
        return std::tie(std::get<indices>(tuple)...);
    }
    (std::make_index_sequence<sizeof...(Elements) - 1>{});
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.