Список предопределенных типов, передаваемый в std :: option - PullRequest
0 голосов
/ 25 января 2019

Есть ли способ создать предопределенный список типов и использовать эти типы в std :: варианта в c ++ 17?Вот что я пытаюсь сделать, он компилируется, но не работает, как я надеялся:

template < class ... Types > struct type_list {};
using valid_types = type_list< int16_t, int32_t, int64_t, double, std::string >;
using value_t = std::variant< valid_types >;

Ответы [ 5 ]

0 голосов
/ 25 января 2019

Это самый короткий и краткий способ сделать это:

template < class ... Types > struct type_list {
  template<template<class...>class Z>
  using apply_to = Z<Types...>;
};

using value_t = value_types::apply_to<std::variant>;

Вы можете полюбить. Например:

template<class T, template<class...>class Z>
struct transcribe_parameters;
template<class T, template<class...>class Z>
using transcribe_parameters_t = typename
  transcribe_parameters<T,Z>::type;
template<template<class...>class Zin, class...Ts, template<class...>class Zout>
struct transcribe_parameters<Zin<Ts...>, Zout> {
  using type=Zout<Ts...>;
};

, что дает вам:

using value_t = transcribe_parameters_t<value_types, std::variant>;

но наличие встроенной функции type_list не представляется необоснованным.

0 голосов
/ 25 января 2019

Если вы в порядке с расширением структуры type_list:

template <class ... Types> struct type_list {
    using variant_type = std::variant< Types...>;
};

Если вы хотите использовать его как отдельную функцию:

template <class T> struct type_list_variant;
template <class... Types> struct type_list_variant<type_list<Types...>> {
    using type = std::variant<Types...>;
};

template <class T>
using type_list_variant_t = typename type_list_variant<T>::type;
0 голосов
/ 25 января 2019

Используя Boost.MP11, это mp_rename:

using value_t = mp_rename< valid_types, std::variant >;

Годболт


В качестве альтернативы, mp_apply - та же операция с перевернутыми операндами, если вы находите ее более читабельной:

using value_t = mp_apply< std::variant, valid_types >;
0 голосов
/ 25 января 2019

Это можно сделать с помощью type_list отправки Types в метафункцию (std::variant):

template < class ... Types > struct type_list {
    template < template < class... > class MFn >
    using apply = MFn< Types... >;
};
// Optional. For nicer calling syntax:
template < template < class... > class MFn, class TypeList >
using apply = typename TypeList::template apply< MFn >;

using valid_types = type_list< int16_t, int32_t, int64_t, double, std::string >;
using value_t = apply< std::variant, valid_types >;

Годболт ссылка

0 голосов
/ 25 января 2019

В одну сторону:

template<class... Types> 
std::variant<Types...> as_variant(type_list<Types...>);

using value_t = decltype(as_variant(valid_types{}));
...