c – 在Boost Phoenix中获取局部变量的类型
发布时间:2020-12-16 07:04:30 所属栏目:百科 来源:网络整理
导读:如何获取范围内Boost Phoenix语句中使用的局部变量类型?使用Phoenix和Proto我可以提取Phoenix表达的许多方面.例如,以下代码公开了arity(3);标签类型(lambda_actor);和Phoenix lambda表达式的child-2标记类型(shift_left): #include boost/proto/proto.hpp#
如何获取范围内Boost Phoenix语句中使用的局部变量类型?使用Phoenix和Proto我可以提取Phoenix表达的许多方面.例如,以下代码公开了arity(3);标签类型(lambda_actor);和Phoenix lambda表达式的child-2标记类型(shift_left):
#include <boost/proto/proto.hpp> #include <boost/phoenix.hpp> namespace proto = boost::proto; namespace phoenix = boost::phoenix; using namespace phoenix::local_names; struct Foo { const char str[6] = " Ok.n"; }; int main(int argc,char *argv[]) { auto f = phoenix::lambda(_a = 17,_b = Foo()) [ std::cout << _a << phoenix::bind(&Foo::str,_b) ]; typedef typename proto::tag_of<decltype( f )>::type tag; typedef typename proto::tag_of<decltype(proto::child_c<2>(f))>::type tagc; static_assert(proto::arity_of<decltype(f)>::value==3,""); static_assert(std::is_same<tag,phoenix::tag::lambda_actor>::value,""); static_assert(std::is_same<tagc,proto::tag::shift_left>::value,""); return 0; } 如何获取局部变量的类型;在这个例子中:_a和_b? 解决方法
我假设你感兴趣的类型是int和Foo,如果这不是你想要的,请忽略这个答案.查看文档,我无法找到获得这些类型的简单方法.但是如果你看一下存储在f中的proto表达式的类型,你可以看到int和Foo可以在第一个子节点内的actor的向量中找到.您可以在输出中看到最终到达有趣类型所需的步骤,然后您可以轻松创建一个可以满足您需要的元函数.在这个简单的例子中,get_local_type使用索引来访问有问题的类型.如果要通过名称访问它(使用_a),您应该能够使用lambda表达式的第二个子项中map_local_index_to_tuple中的数据来获取与名称关联的索引.使用定义为
here的phoenix :: detail :: get_index实现get_local_type_from_name也非常简单.这个元函数需要上面提到的映射作为它的第一个参数和你想要信息的占位符的类型(更具体地说它需要phoenix :: detail :: local< phoenix :: local_names :: _ a_key>,你可以使用proto获得它:: result_of ::占位符类型的值)作为第二个.
#include <iostream> #include <typeinfo> #include <string> #include <cxxabi.h> #include <type_traits> #include <boost/proto/proto.hpp> #include <boost/phoenix.hpp> namespace proto = boost::proto; namespace phoenix = boost::phoenix; using namespace phoenix::local_names; namespace fusion = boost::fusion; struct Foo { const char str[6] = " Ok.n"; }; std::string demangle(const char* mangledName) { int status; char* result = abi::__cxa_demangle(mangledName,nullptr,&status); switch(status) { case -1: std::cerr << "Out of memory!" << std::endl; exit(1); case -2: return mangledName; case -3: // Should never happen,but just in case? return mangledName; } std::string name = result; free(result); return name; } template <typename Lambda,int N> struct get_local_type { typedef typename proto::result_of::value<typename proto::result_of::child_c<Lambda,0>::type >::type vector_of_locals_type; typedef typename proto::result_of::value<typename fusion::result_of::at_c<vector_of_locals_type,N>::type >::type ref_type; typedef typename std::remove_reference<ref_type>::type type; }; template <typename Lambda,typename Arg> struct get_local_type_from_name { typedef typename proto::result_of::value<Arg>::type local_name; typedef typename proto::result_of::value<typename proto::result_of::child_c<Lambda,1>::type >::type map_type; typedef typename phoenix::detail::get_index<map_type,local_name>::type index; typedef typename get_local_type<Lambda,index::value>::type type; }; int main(int argc,char *argv[]) { auto f = phoenix::lambda(_b = 17,_a = Foo()) [ std::cout << _b << phoenix::bind(&Foo::str,_a) ]; std::cout << std::endl << "This is the whole lambda expression:" << std::endl; std::cout << std::endl << demangle(typeid(f).name()) << std::endl; std::cout << std::endl << "Take the first child:" << std::endl; std::cout << std::endl << demangle(typeid(proto::child_c<0>(f)).name()) << std::endl; std::cout << std::endl << "Then its value (this is a vector that contains the types you want):" << std::endl; std::cout << std::endl << demangle(typeid(proto::value(proto::child_c<0>(f))).name()) << std::endl; std::cout << std::endl << "Take the first element of that vector:" << std::endl; std::cout << std::endl << demangle(typeid(fusion::at_c<0>(proto::value(proto::child_c<0>(f)))).name()) << std::endl; std::cout << std::endl << "Take the value of that element:" << std::endl; std::cout << std::endl << demangle(typeid(proto::value(fusion::at_c<0>(proto::value(proto::child_c<0>(f))))).name()) << std::endl; typedef typename proto::tag_of<decltype( f )>::type tag; typedef typename proto::tag_of<decltype(proto::child_c<2>(f))>::type tagc; static_assert(proto::arity_of<decltype(f)>::value==3,""); typedef typename get_local_type<decltype(f),0>::type type_of_1st; typedef typename get_local_type<decltype(f),1>::type type_of_2nd; typedef typename get_local_type_from_name<decltype(f),_a_type>::type type_of_a; typedef typename get_local_type_from_name<decltype(f),decltype(_b)>::type type_of_b; static_assert(std::is_same<type_of_1st,int>::value,""); static_assert(std::is_same<type_of_2nd,Foo>::value,""); static_assert(std::is_same<type_of_a,""); static_assert(std::is_same<type_of_b,""); return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |