Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I'm assuming that the types you are interested in are <code>int</code> and <code>Foo</code>, if this is not what you are after please disregard this answer. Looking over the documentation I haven't been able to find an easy way to get these types. But if you look at the type of the proto expression stored in <code>f</code> you can see that <code>int</code> and <code>Foo</code> can be found in a vector of actors inside the first child. The steps you need to make to finally get to the interesting types can be seen in the output and following that you can easily create a metafunction that does what you want. In this simple case <code>get_local_type</code> uses an index to access the type in question. If you want to access it via name (using <code>_a</code>) you should be able to get the index associated with a name using the data in <code>map_local_index_to_tuple</code> in the second child of the lambda expression. Using <code>phoenix::detail::get_index</code> that is defined <a href="http://www.boost.org/boost/phoenix/scope/detail/local_variable.hpp" rel="nofollow">here</a> implementing <code>get_local_type_from_name</code> is also pretty easy. This metafunction expects the map mentioned above as its first argument and the type of the placeholder you want information from (more specifically it needs <code>phoenix::detail::local&lt;phoenix::local_names::_a_key&gt;</code>, and you can get that using <code>proto::result_of::value</code> on the type of the placeholder) as its second.</p> <pre><code>#include &lt;iostream&gt; #include &lt;typeinfo&gt; #include &lt;string&gt; #include &lt;cxxabi.h&gt; #include &lt;type_traits&gt; #include &lt;boost/proto/proto.hpp&gt; #include &lt;boost/phoenix.hpp&gt; 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, nullptr, &amp;status); switch(status) { case -1: std::cerr &lt;&lt; "Out of memory!" &lt;&lt; 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 &lt;typename Lambda, int N&gt; struct get_local_type { typedef typename proto::result_of::value&lt;typename proto::result_of::child_c&lt;Lambda,0&gt;::type &gt;::type vector_of_locals_type; typedef typename proto::result_of::value&lt;typename fusion::result_of::at_c&lt;vector_of_locals_type,N&gt;::type &gt;::type ref_type; typedef typename std::remove_reference&lt;ref_type&gt;::type type; }; template &lt;typename Lambda, typename Arg&gt; struct get_local_type_from_name { typedef typename proto::result_of::value&lt;Arg&gt;::type local_name; typedef typename proto::result_of::value&lt;typename proto::result_of::child_c&lt;Lambda,1&gt;::type &gt;::type map_type; typedef typename phoenix::detail::get_index&lt;map_type,local_name&gt;::type index; typedef typename get_local_type&lt;Lambda,index::value&gt;::type type; }; int main(int argc, char *argv[]) { auto f = phoenix::lambda(_b = 17, _a = Foo()) [ std::cout &lt;&lt; _b &lt;&lt; phoenix::bind(&amp;Foo::str,_a) ]; std::cout &lt;&lt; std::endl &lt;&lt; "This is the whole lambda expression:" &lt;&lt; std::endl; std::cout &lt;&lt; std::endl &lt;&lt; demangle(typeid(f).name()) &lt;&lt; std::endl; std::cout &lt;&lt; std::endl &lt;&lt; "Take the first child:" &lt;&lt; std::endl; std::cout &lt;&lt; std::endl &lt;&lt; demangle(typeid(proto::child_c&lt;0&gt;(f)).name()) &lt;&lt; std::endl; std::cout &lt;&lt; std::endl &lt;&lt; "Then its value (this is a vector that contains the types you want):" &lt;&lt; std::endl; std::cout &lt;&lt; std::endl &lt;&lt; demangle(typeid(proto::value(proto::child_c&lt;0&gt;(f))).name()) &lt;&lt; std::endl; std::cout &lt;&lt; std::endl &lt;&lt; "Take the first element of that vector:" &lt;&lt; std::endl; std::cout &lt;&lt; std::endl &lt;&lt; demangle(typeid(fusion::at_c&lt;0&gt;(proto::value(proto::child_c&lt;0&gt;(f)))).name()) &lt;&lt; std::endl; std::cout &lt;&lt; std::endl &lt;&lt; "Take the value of that element:" &lt;&lt; std::endl; std::cout &lt;&lt; std::endl &lt;&lt; demangle(typeid(proto::value(fusion::at_c&lt;0&gt;(proto::value(proto::child_c&lt;0&gt;(f))))).name()) &lt;&lt; std::endl; typedef typename proto::tag_of&lt;decltype( f )&gt;::type tag; typedef typename proto::tag_of&lt;decltype(proto::child_c&lt;2&gt;(f))&gt;::type tagc; static_assert(proto::arity_of&lt;decltype(f)&gt;::value==3,""); static_assert(std::is_same&lt;tag, phoenix::tag::lambda_actor&gt;::value,""); static_assert(std::is_same&lt;tagc, proto::tag::shift_left&gt;::value,""); typedef typename get_local_type&lt;decltype(f),0&gt;::type type_of_1st; typedef typename get_local_type&lt;decltype(f),1&gt;::type type_of_2nd; typedef typename get_local_type_from_name&lt;decltype(f),_a_type&gt;::type type_of_a; typedef typename get_local_type_from_name&lt;decltype(f),decltype(_b)&gt;::type type_of_b; static_assert(std::is_same&lt;type_of_1st,int&gt;::value,""); static_assert(std::is_same&lt;type_of_2nd,Foo&gt;::value,""); static_assert(std::is_same&lt;type_of_a,Foo&gt;::value,""); static_assert(std::is_same&lt;type_of_b,int&gt;::value,""); return 0; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload