这是对这个答案的后续问题的提取。
给出以下“循环”技术
// loop.hpp
模板<的std :: …
运用 Boost.Mp11 ,第一个版本是:
static constexpr auto size = std::tuple_size_v<Types>; mp_for_each<mp_iota_c<size>>([&] (auto i) { /* ... */ });
在模板上执行此操作的方式基本相同:
using list = mp_list<mp_quote<std::tuple>, mp_quote<std::pair>>; mp_for_each<list>([&](auto f){ // v is a tuple<int, char> the first time around and a pair<int, char> // the second time around mp_invoke_q<decltype(f), int, char> v; });
当然,你可以做任何你想做的事 f 在身体中,我只是以它为例来调用它 mp_quote 以及它与Mp11其余部分的整合程度。
f
mp_quote
您可以包装表单的模板 template<class...> class 进入类似以下的标记类型:
template<class...> class
#pragma once // template_tag.hpp #include <tuple> #include <type_traits> template< template<class...> class Tmpl_ > struct TemplateTag { template<class... Ts> using insert = Tmpl_<Ts...>; template< template<template<class... > class> class TmplTmpl > using rewrap_into = TmplTmpl<Tmpl_>; }; // convenience helper template<class TmplTag, class... Ts> using InsertTemplateArgs = typename TmplTag::template insert<Ts...>; static_assert( std::is_same< InsertTemplateArgs< TemplateTag<std::tuple>, int, bool >, std::tuple<int, bool> >{} ); // convenience helper template<class TmplTag, template<template<class...> class> class TmplTmpl> using RewrapTemplateInto = typename TmplTag::template rewrap_into<TmplTmpl>; template<template<class...> class Tmpl> struct OtherTemplateTag {}; static_assert( std::is_same< RewrapTemplateInto< TemplateTag<std::tuple>, OtherTemplateTag >, OtherTemplateTag<std::tuple> >{} );
将模板包装到标签中后 类型 ,您可以像以前一样迭代这些类型:
#include <iostream> #include <string_view> #include <tuple> #include <utility> #include <variant> #include "loop.hpp" #include "template_tag.hpp" template<class T> std::string_view inspect() { return __PRETTY_FUNCTION__; } using Templates = std::tuple< TemplateTag<std::tuple>, TemplateTag<std::tuple>, TemplateTag<std::pair>, TemplateTag<std::variant> >; template< template<class...> class Tmpl > struct AnotherTemplateTag {}; int main() { loop(std::tuple_size<Templates>{}, [&] (auto i) { using TmplTag = std::tuple_element_t<i, Templates>; std::cout << i << ": " << inspect<TmplTag>() << "\n"; using AnotherTmplTag = RewrapTemplateInto<TmplTag, AnotherTemplateTag>; std::cout << " " << inspect<AnotherTmplTag>() << "\n"; using TmplWithArgs = InsertTemplateArgs<TmplTag, int, long>; std::cout << " " << inspect<TmplWithArgs>() << "\n"; }); }