От списка типов к пакету аргументов

У меня есть typelist формы, описанной здесь:

http://www.drdobbs.com/generic-programmingtypelists-and-applica/184403813

У каждого типа есть функция утиного типа (виртуальный шаблон/время компиляции) с именем get(), которая возвращает простой тип, подобный этому:

struct Float {
  float get() { return 7.0; }
};
struct Int {
  int get() { return 7; }
};
typedef typelist<Float, typelist<Int, null_typelist>> types;

У меня также есть функция, которая принимает вариативное число аргументов простого типа, например:

template<typename... Args>
foo(Args... args)
{
}

Теперь мне нужен способ вызова foo с учетом types. Я думаю, что для этого есть решение с помощью кортежа, но я действительно далек от решения, которое работает... Надеюсь, вы можете мне помочь здесь!


person XPlatformer    schedule 24.07.2014    source источник
comment
Почему вы используете списки типов C++03 в C++11?!   -  person Yakk - Adam Nevraumont    schedule 24.07.2014
comment
Рассматриваемый список типов возвращается классом до его создания. Есть ли лучший способ сделать это в С++ 11?   -  person XPlatformer    schedule 24.07.2014
comment
Я не понимаю, что вы пытаетесь сделать: типы — это тип (например, int), и вы хотите вызвать функцию, которая ожидает экземпляры некоторых типов (например, 7). Если у вас есть какой-то объект, похожий на кортеж, тогда должно быть возможно делать то, что вы хотите.   -  person MadScientist    schedule 24.07.2014
comment
template<class...>struct types{using type=types;}; — это список типов стиля C++11. (using type=types; необязательно)   -  person Yakk - Adam Nevraumont    schedule 24.07.2014
comment
@Yakk, это может быть полезно. Как тогда будет выглядеть список типов для моего примера, где он содержит F и I?   -  person XPlatformer    schedule 24.07.2014
comment
Было бы types<F,I> вместо type_list< F, type_list< I, null_typelist >>.   -  person Yakk - Adam Nevraumont    schedule 24.07.2014
comment
Не могли бы вы дать мне ссылку на более сложный пример, пожалуйста? Кажется, я не могу заставить его сделать что-то полезное.   -  person XPlatformer    schedule 24.07.2014


Ответы (1)


Этот код преобразует typelist в tuple и вызывает foo с простыми типами.

#include <tuple>
#include <iostream>

template<typename H, typename T>
struct typelist
{
    typedef H Head;
    typedef T Tail;
};

struct null_typelist {};


template<int... Indices>
struct indices {
    using next = indices<Indices..., sizeof...(Indices)>;
};

template<int Size>
struct build_indices {
    using type = typename build_indices<Size - 1>::type::next;
};

template<>
struct build_indices<0> {
    using type = indices<>;
};

template<typename T>
using Bare = typename std::remove_cv<typename std::remove_reference<T>::type>::type;

template<typename Tuple>
constexpr
typename build_indices<std::tuple_size<Bare<Tuple>>::value>::type
make_indices()
{ return {}; }

template<typename T, typename... Args>
struct tuple_push;

template<typename T, typename... Args>
struct tuple_push<T, std::tuple<Args...>>
{
    typedef std::tuple<Args..., T> type;
};

template<typename TL>
struct typelist_to_tuple;

template<typename H, typename T>
struct typelist_to_tuple<typelist<H, T>>
{
    typedef typename tuple_push<H, typename typelist_to_tuple<T>::type>::type type;
};

template<typename H>
struct typelist_to_tuple<typelist<H, null_typelist>>
{
    typedef std::tuple<H> type;
};

struct Float {
  float get() const { return 7.5; }
};
struct Int {
  int get() const { return 7; }
};

template<typename... Args>
void foo(const Args&... args)
{
}

template<typename T, typename... Args>
void foo(const T& current, const Args&... args)
{
    std::cout << current << std::endl;
    foo(args...);
}

template<typename Tuple, int... Indices>
void apply(const Tuple& tuple, indices<Indices...>)
{
    foo(std::get<Indices>(tuple).get()...);
}

template<typename Tuple>
void apply(const Tuple& tuple)
{
    apply(tuple, make_indices<Tuple>());
}

int main()
{
    typedef typelist<Int, typelist<Float, typelist<Int, null_typelist>>> list;
    typedef typelist_to_tuple<list>::type tuple;
    tuple t = std::make_tuple(Int(), Float(), Int());
    apply(t);
}

живой пример

person ForEveR    schedule 24.07.2014
comment
Как работает build_indices? А для чего нужен sizeof...(Indices)? - person 0x499602D2; 26.07.2014