Note that there are some explanatory texts on larger screens.

plurals
  1. POBoost::Variant and function_types in it: How to put functions into Boost::variant?
    primarykey
    data
    text
    <p><strong>Lyrics:</strong></p> <p>I try to implement a task pool over MPI. So I need some kind of RPC but one that would work between different parts of my program, meaning processor A wants processor B to call function C with argument D. We can not pass pointers to functions between processes like we do with threads, so we need some wrapper container to hold our function pointers at each process instance. All inside one source file\one program... So I started wondering about <a href="https://stackoverflow.com/questions/8304582/how-to-store-functional-objects-with-difrent-signature-in-a-container-eg-std">How to store functional objects with different signature in a container</a>. My API Idea back then was wrong - it is better to define all functions in function pool at that pool construction (at least it shall be much easier to implement). But while implementing I faced next trouble: </p> <p><strong>Problem:</strong></p> <p>Such simple code (<a href="http://www.boost.org/doc/libs/1_48_0/libs/function_types/doc/html/boost_functiontypes/introduction.html" rel="nofollow noreferrer">function_types</a>, <a href="http://www.boost.org/doc/libs/1_37_0/libs/mpl/doc/refmanual/vector.html" rel="nofollow noreferrer">mpl::vector</a>, <a href="http://www.boost.org/doc/libs/1_48_0/doc/html/variant.html" rel="nofollow noreferrer">variant</a>):</p> <pre><code>#include &lt;boost/function_types/function_type.hpp&gt; #include &lt;boost/mpl/vector.hpp&gt; #include &lt;boost/mpl/vector_c.hpp&gt; #include &lt;boost/variant.hpp&gt; #include &lt;iostream&gt; #include &lt;string&gt; template &lt;class T&gt; int append(T val) { std::cout &lt;&lt; "hello"; return 0; } int main() { boost::variant&lt;boost::function_types::function_type&lt; boost::mpl::vector&lt;int,int&gt; &gt;::type , boost::function_types::function_type&lt; boost::mpl::vector&lt;int,std::string&gt; &gt;::type &gt; a; return 0; } </code></pre> <p>Will not compile falling with:</p> <pre><code>Error 1 error C2066: cast to function type is illegal c:\program files\boost\include\boost\variant\variant.hpp 1231 1 </code></pre> <p>And looking at <a href="http://svn.boost.org/svn/boost/trunk/boost/variant/variant.hpp" rel="nofollow noreferrer">source</a> we see:</p> <p>this code block:</p> <pre><code>variant() { // NOTE TO USER : // Compile error from here indicates that the first bound // type is not default-constructible, and so variant cannot // support its own default-construction. // new( storage_.address() ) internal_T0(); indicate_which(0); // zero is the index of the first bounded type } </code></pre> <p>So I wonder: How to get around this error?</p> <p>Also I tried:</p> <pre><code>#include &lt;boost/function_types/function_type.hpp&gt; #include &lt;boost/mpl/vector.hpp&gt; #include &lt;boost/mpl/vector_c.hpp&gt; #include &lt;boost/variant.hpp&gt; #include &lt;boost/function.hpp&gt; #include &lt;iostream&gt; #include &lt;string&gt; template &lt;class T&gt; int append(T val) { std::cout &lt;&lt; "hello"; return 1; } int main() { boost::variant&lt; boost::function&lt;int (std::string) &gt;, boost::function&lt;int (int) &gt; &gt; a; a= &amp;append&lt;int&gt;; return 0; } </code></pre> <p>Which fails with:</p> <pre><code>Error 1 error C2668: 'boost::detail::variant::make_initializer_node::apply&lt;BaseIndexPair,Iterator&gt;::initializer_node::initialize' : ambiguous call to overloaded function c:\program files\boost\include\boost\variant\variant.hpp 1330 </code></pre> <p>Any Ideas on how to make boost.variant hold functions?</p> <p>Of course we can play with shared pointers to functors like so:</p> <pre><code>#include &lt;boost/variant.hpp&gt; #include &lt;boost/shared_ptr.hpp&gt; #include &lt;iostream&gt; #include &lt;string&gt; template &lt;class in, class out&gt; struct s_append { out operator()(in val) { std::cout &lt;&lt; "hello"; return out(); } }; int main() { boost::variant&lt;boost::shared_ptr&lt;s_append&lt;int, int&gt; &gt;, boost::shared_ptr&lt; s_append&lt;std::string, int&gt; &gt; &gt; a; boost::shared_ptr&lt;s_append&lt;int, int&gt; &gt; b(new s_append&lt;int, int&gt; ); a=b; return 0; } </code></pre> <p>and it would compile but resulting API sucks - you have to 1) create functors for all functions you want to use (meaning limit there use of current process scope); 2) use shared_pointers and so I don't really even get how to call functions nested that way (simple first guess <code>(*a)(22);</code> just won't compile =( and API starts to be as bad as we would have using Boost.Any).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    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