преобразовать типы кортежей в типы распада - PullRequest
0 голосов
/ 12 июля 2020

Я играю с C ++ 17, и у меня есть std::tuple из const &T типов. Например:

template <typename... members>
auto make_cr_tuple(members const &...args) -> decltype(auto) {
    return std::make_tuple(std::cref(args)...);
}

int main() {
    std::string s;
    int i = 0;
    auto crt = make_cr_tuple(s, i); // std::tuple<const std::string &, const int &>
}

Мне нужен способ объявить кортеж каждого из типов значений, удалив квалификаторы const и reference. Например, может быть что-то вроде этого:

    using decayed = decayed_tuple<decltype(crt)>::type

Я думаю, что мог бы использовать что-то вроде этого, но этого недостаточно.

template <typename T>
struct decayed_tuple {
    using type = decltype(std::apply(std::make_tuple, T{}));
};

Очевидно, это не работает, потому что make_tuple - это неразрешенная перегруженная функция.

На самом деле мне нужно std::make_tuple<???>, но я не знаю, как получить типы из T в пакет шаблонов. Обратите внимание, что я предполагаю, что T здесь конструктивно по умолчанию.

Ответы [ 2 ]

3 голосов
/ 12 июля 2020

Возможно, вы можете объявить (определение не требуется) функцию следующим образом

template <typename ... Ts>
constexpr auto decay_types (std::tuple<Ts...> const &)
   -> std::tuple<std::remove_cv_t<std::remove_reference_t<Ts>>...>;

и использовать ее через std::declval() и decltype().

Возможно, вы также можете добавить using псевдоним для упрощения работы

template <typename T>
using decay_tuple = decltype(decay_types(std::declval<T>()));

Полный пример

#include <tuple>
#include <type_traits>

template <typename ... Ts>
constexpr auto decay_types (std::tuple<Ts...> const &)
   -> std::tuple<std::remove_cv_t<std::remove_reference_t<Ts>>...>;

template <typename T>
using decay_tuple = decltype(decay_types(std::declval<T>()));

int main()
 {
   using T1 = std::tuple<int const &, long const &, long long const &>;
   using T2 = decay_tuple<T1>;

   static_assert( std::is_same_v<T2, std::tuple<int, long, long long>>, "!");
 }
2 голосов
/ 12 июля 2020

С Boost.Mp11 , это короткий однострочник (как всегда):

template <typename Tuple>
using decayed_tuple = mp_transform<std::decay_t, Tuple>;
...