2014-07-24 44 views
1

我这里所描述的形式的类型串:从类型串到参数包

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。我认为有一个解决方案,通过元组,但我真的很远离解决方案... 我希望你能帮助我在这里!

+0

为什么要使用C++ 11 C++ 03的类型串? – Yakk

+0

问题中的类型列表在构造之前由类“返回”。有没有更好的方式在C++ 11中做到这一点? – XPlatformer

+0

我不明白你在做什么:types是一个类型(如int),你想调用一个需要某些类型实例(如7)的函数。如果你有某种类似元组的对象,那么应该可以做你想做的事情。 – MadScientist

回答

2

此代码将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); 
} 

live example

+0

build_indices是如何工作的?什么是sizeof ...(指数)? – 0x499602D2