Boost :: Variant and functions_types in it: how to put functions in Boost :: variant?

Text:

I am trying to implement an MPI task pool. Therefore, I need some kind of RPC, but one that will work between different parts of my program, that is, processor A wants processor B to call function C with argument D. We cannot pass pointers to functions between processes, as we do with threads, so we need some kind of container container for storing pointers to each process instance. Everything inside one source file \ one program ... So I started to wonder about How to store functional objects with a different signature in the container . My idea of โ€‹โ€‹the API was wrong then - itโ€™s better to define all the functions in the function pool when building this pool (at least it will be much easier to implement). But during implementation, I ran into the following problem:

Problem:

Such simple code ( function_types , mpl :: vector , variant ):

#include <boost/function_types/function_type.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/vector_c.hpp> #include <boost/variant.hpp> #include <iostream> #include <string> template <class T> int append(T val) { std::cout << "hello"; return 0; } int main() { boost::variant<boost::function_types::function_type< boost::mpl::vector<int,int> >::type , boost::function_types::function_type< boost::mpl::vector<int,std::string> >::type > a; return 0; } 

Will not compile with:

 Error 1 error C2066: cast to function type is illegal c:\program files\boost\include\boost\variant\variant.hpp 1231 1 

And looking at the source , we see:

this code block:

 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 } 

So, I am wondering: how to get around this error?

Also I tried:

 #include <boost/function_types/function_type.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/vector_c.hpp> #include <boost/variant.hpp> #include <boost/function.hpp> #include <iostream> #include <string> template <class T> int append(T val) { std::cout << "hello"; return 1; } int main() { boost::variant< boost::function<int (std::string) >, boost::function<int (int) > > a; a= &append<int>; return 0; } 

Failure:

 Error 1 error C2668: 'boost::detail::variant::make_initializer_node::apply<BaseIndexPair,Iterator>::initializer_node::initialize' : ambiguous call to overloaded function c:\program files\boost\include\boost\variant\variant.hpp 1330 

Any ideas on how to make boost.variant hold functions?

Of course, we can play with common pointers to such functors:

 #include <boost/variant.hpp> #include <boost/shared_ptr.hpp> #include <iostream> #include <string> template <class in, class out> struct s_append { out operator()(in val) { std::cout << "hello"; return out(); } }; int main() { boost::variant<boost::shared_ptr<s_append<int, int> >, boost::shared_ptr< s_append<std::string, int> > > a; boost::shared_ptr<s_append<int, int> > b(new s_append<int, int> ); a=b; return 0; } 

and it will compile, but as a result of the API sucks - you need 1) to create functors for all the functions that you want to use (which means limiting the use of the current process area); 2) use shared_pointers, and therefore I donโ€™t even understand how to call functions nested this way (a simple first guess (*a)(22); just wonโ€™t compile = (and the API will start to be as bad as we would use Boost .Any).

+1
source share
1 answer

Try introducing a dummy type as the first argument to variant . Because the comment you found explains that for a custom constructor variant, only the first type in the variant is used by default. An empty structure type ( struct NoFunction {}; ) can be used for this.

However, you may have had something with the idea of โ€‹โ€‹using boost :: functions as types in a variant ... at least by default. Iโ€™m not sure that the other error you made as a result of this approach was caused, but I just wanted to tell you that you can continue this angle more if you cannot use a workaround like the dummy type that I mentioned.

0
source

Source: https://habr.com/ru/post/1387294/


All Articles