[英]Mapping a std::tuple to another std::tuple
假設我有一個std::tuple<Types...>
,我想生成一個std::tuple<std::priority_queue<Types...>>
#include <queue>
#include <tuple>
template<typename TypesTuple>
struct Bar {
std::priority_queue<std::for_each_tuple_type(TypesTuple)...> queues;
};
using Foo = Bar<std::tuple<int, double>>;
如何實現?
編輯
使用boost :: tuple或vector進行轉換會變得更容易嗎? 可以在元級別應用轉換嗎?
您可以使用部分專業化:
template<typename TypesTuple>
struct Bar;
template<typename... Ts>
struct Bar<std::tuple<Ts...>> {
std::tuple<std::priority_queue<Ts>...> queues;
};
因此my_bar.queue
的類型將為std::tuple<std::priority_queue<int>, std::priority_queue<double>>
。
其他方式:
template<class... Types>
std::tuple<std::priority_queue<Types...>> convert(std::tuple<Types...>);
using Foo = decltype(convert(std::declval<std::tuple<int>>());
但是,僅當元組包含1到3個元素並且它們滿足std::priority_queue
模板參數要求時,該方法才有效,例如:
using Foo = decltype(convert( std::declval<std::tuple<int, std::vector<int>, std::less<int> > >() ));
template<class In, template<class...>class Map>
struct template_map;
template<class In, template<class...>class Map>
using template_map_t=typename template_map<In, Map>::type;
template<template<class...>class Z, class...Ts, template<class...>class Map>
struct template_map<Z<Ts...>, Map> {
using type=Z<Map<Ts>...>;
};
這將使用一個作為類型之上的模板的類型和一個類型映射,並在通過映射映射包含的類型之后返回該類型。
template<typename TypesTuple>
struct Bar {
template_map_t<TypesTuple, std::priority_queue> queues;
};
using Foo = Bar<std::tuple<int, double>>;
編寫template_map_t
可以通過多種方式完成。
雖然我不建議這樣做,但這是一種哈娜風格:
template<class T>struct tag_t{ constexpr tag_t() {}; using type=T; };
template<class T>constexpr tag_t<T> tag{};
template<template<class...>class Z>
struct ztemplate_t{
constexpr ztemplate_t() {};
template<class...Ts>using apply=Z<Ts...>;
};
template<template<class...>class Z>
constexpr ztemplate_t<Z> ztemplate{};
這些是constexpr值,分別存儲類型和模板。
template<class Z, class...Ts>
constexpr auto zapply( Z, tag_t<Ts>... )
-> tag_t< typename Z::template apply<Ts...> >
{ return {}; }
zapply
現在允許我們使用值將模板應用於類型。
我們現在可以編寫一個map函數:
template<template<class...>class Z, class...Ts, class zM>
constexpr auto zmap( tag_t<Z<Ts...>>, zM )
{ return zapply( ztemplate<Z>, zapply( zM{}, tag<Ts> )... ); }
並提取類型:
template<class Tag>using type_t=typename Tag::type;
template<typename TypesTuple>
struct Bar {
using queues_t = type_t<decltype(
zmap( tag<TypesTuple>, ztemplate<std::priority_queue> )
)>;
queues_t queues;
};
帶有測試代碼:
using Foo = Bar<std::tuple<int, double>>;
tag_t< std::tuple< std::priority_queue<int>, std::priority_queue<double> > > test = tag< decltype( std::declval<Foo&>().queues ) >;
該圖顯示了類型映射的工作原理。
現場例子 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.