#include <type_traits>
#include <cstddef>
#include <tuple>
using std::size_t;
/*
构建单个type_list
. 然后构建tuple
from said type_list
,并得到类似的索引。
基本元编程样板:
*/
template<typename... Ts>
struct type_list {};
template<typename T, typename list, typename=void>
struct index_of;
template<typename T, typename T0, typename...Ts>
struct index_of<T, type_list<T0, Ts...>, typename std::enable_if<
std::is_same<T, T0>::value
>::type>: std::integral_constant< size_t, 0 >{};
template<typename T, typename T0, typename...Ts>
struct index_of<T, type_list<T0, Ts...>, typename std::enable_if<
!std::is_same<T, T0>::value
>::type>: std::integral_constant< size_t, index_of<T, type_list<Ts...>>::value+1 >{};
template<template<typename...>class target, typename source>
struct copy_types;
template<template<typename...>class target, template<typename...>class src, typename... Ts>
struct copy_types<target, src<Ts...>> {
typedef target<Ts...> type;
};
template<template<typename...>class target, typename source>
using CopyTypes = typename copy_types<target, source>::type;
/*
现在我们创建一个类型列表,并使用它来定义我们的元组和一个get
函数:
*/
typedef type_list<int, double, char> my_types;
typedef CopyTypes< std::tuple, my_types > my_tuple;
template<typename T>
T& get_type( my_tuple& t ) {
return std::get< index_of<T, my_types>::value >(t);
}
template<typename T>
T const& get_type( my_tuple const& t ) {
return std::get< index_of<T, my_types>::value >(t);
}
/*
如果我们想要标记类型,我们可以使用boost::mpl
,或者像这样快速滚动:
*/
template<typename Tag, typename T>
struct tagged_type {
typedef Tag tag;
typedef T type;
};
template< typename tagged_type >
using GetType = typename tagged_type::type;
template< typename tagged_type >
using GetTag = typename tagged_type::tag;
template< template<typename...> class target, typename tagged_list >
struct copy_tagged_types;
template< template<typename...> class target, typename... tagged_Ts >
struct copy_tagged_types< target, type_list<tagged_Ts...> >:
copy_types< target, type_list< GetType<tagged_Ts>... > >
{};
template< template<typename...> class target, typename tagged_list >
using CopyTaggedTypes = typename copy_tagged_types< target, tagged_list >::type;
template< typename Tag, typename tagged_list >
struct get_tag_index;
template< typename Tag, typename...Tagged_Ts >
struct get_tag_index< Tag, type_list< Tagged_Ts...> >:
index_of< Tag, type_list< GetTag<Tagged_Ts>... > > {};
/*
现在我们有了标记模板元编程库的基础知识。
使用将类似于:
*/
typedef type_list<
tagged_type<struct bob, int>,
tagged_type<struct alice, int>
> my_tagged_types;
typedef CopyTaggedTypes< std::tuple, my_tagged_types > my_tuple2;
template<typename Tag>
auto get_tag( my_tuple2& tup )
->decltype(std::get< get_tag_index< Tag, my_tagged_types >::value >( tup ))
{
return std::get< get_tag_index< Tag, my_tagged_types >::value >( tup );
}
template<typename Tag>
auto get_tag( my_tuple2 const& tup )
->decltype(std::get< get_tag_index< Tag, my_tagged_types >::value >( tup ))
{
return std::get< get_tag_index< Tag, my_tagged_types >::value >( tup );
}
/*
这基本上是“自己动手boost::mpl
”的情况。:)这里的例子
*/
int main() {
my_tuple t1;
get_type<char>(t1) = 'a';
my_tuple2 t2;
get_tag<bob>(t2) = 7;
}