Boost.Variant, Boost.MPL: How to add types?

I look at this boost.Any-based lattice code and can't help but wonder if we can use Boost.Variant . I wonder if such an API is possible:

void voidFunc() { std::cout << "void called" << std::endl; } int stringFunc(std::string str) { std::cout << str << std::endl; return 0; } int main() { some_map_like_type<std::string, boost::variant> funcs; funcs.insert<void , void >("voidFunc", &voidFunc)); // now our variant vould contain something like boost::function<void, void> funcs.insert<int , std::string>("stringFunc", &stringFunc)); // and now we added to our variant a new type: boost::function<int , std::string> funcs.insert<void , void >("voidFunc2", &voidFunc)); // and now our variant should not change because it already contains boost::function<void, void> type // And here when all the fun part is: funcs["voidFunc"](); // compiles funcs["stringFunc"]("hello"); // compiles funcs["stringFunc"](some_not_std_string_class); // does not compile. return 0; } 

This means that at the end, the compiler should have compiled something like:

 void voidFunc() { std::cout << "void called" << std::endl; } int stringFunc(std::string str) { std::cout << str << std::endl; return 0; } int main() { some_map_like_type<std::string, boost::variant< boost::function<void , void>, boost::function<int , std::string> > > funcs; funcs.insert<void , void >("voidFunc", &voidFunc)); // now our variant vould contain something like boost::function<void, void> funcs.insert<int , std::string>("stringFunc", &stringFunc)); // and now we added to our variant a new type: boost::function<int , std::string> funcs.insert<void , void >("voidFunc2", &voidFunc)); // and now our variant should not change because it already contains boost::function<void, void> type // And here when all the fun part is: funcs["voidFunc"](); // compiles funcs["stringFunc"]("hello"); // compiles funcs["stringFunc"](some_not_std_string_class); // here it would give error and would not compile return 0; } 

Update:

What I tried (based on this Variant docs and the MPL Demo and docs ):

 #include <boost/static_assert.hpp> #include <boost/mpl/equal.hpp> #include <boost/mpl/vector_c.hpp> #include <boost/mpl/transform.hpp> #include <boost/mpl/multiplies.hpp> #include <boost/mpl/placeholders.hpp> #include <boost/variant.hpp> #include <iostream> #include <string> #include <vector> class sudo_science { public: typedef boost::mpl::vector_c<int> types_vector1; typedef boost::make_recursive_variant< types_vector1 >::type recursive_variant_t; std::vector< recursive_variant_t > variant_seq; template <typename T> void append(T val) { typedef boost::mpl::push_back<types_vector1,T>::type types_vector1; variant_seq.push_back(val); return; } std::vector< recursive_variant_t > give_me_end_variant() { return variant_seq; } }; int main() { sudo_science a; a.append<float>(1.0); a.append<std::string>("Stack and Boost"); //sorry for C++11 auto varint = a.give_me_end_variant(); return 0; } 

But it does not compile with two identical errors:

 Error 1 error C2665: 'boost::detail::variant::make_initializer_node::apply<BaseIndexPair,Iterator>::initializer_node::initialize' : none of the 2 overloads could convert all the argument types c:\program files\boost\include\boost\variant\variant.hpp 1330 1 
0
source share
1 answer

It's impossible. operator[] is runtime, and types are compile-time things. So should the compiler compile the following?

 char const* str; if (some_condition()) str = "voidFunc"; else str = "stringFunc"; // ... some more code if (some_condition()) funcs[str](); else funcs[str](str); 

How should the compiler know if the second call to some_condition() gives the same result as before? Or was there code between the modified str value?

How about the following:

 void call(some_map_like_type<std::string, boost::variant> const& funcs) { funcs["voidFunc"](); } 

How should the compiler know if the funcs call time funcs mapping of the "voidFunc" to a function with no arguments? And what should happen if it is called once with a value that does, and once with a value that is not?

Depending on what you really want to achieve, there may be a way to get it using templates and constexpr functions. However, note that nothing that happens at runtime can affect code compilation for the simple reason that code cannot be run before it is compiled.

-1
source

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


All Articles