Extending boost option with MPL list

I am trying to provide the program with a way to add new objects to an option in the library, but I am encountering some cryptic errors.

#include <boost/mpl/copy.hpp> #include <boost/mpl/joint_view.hpp> #include <boost/mpl/list.hpp> #include <boost/variant/variant.hpp> struct InternalType1 {}; struct InternalType2 {}; template <typename LocalTypes> struct Foo { typedef boost::mpl::list< InternalType1, InternalType2 > Types; typename boost::make_variant_over< typename boost::mpl::joint_view< Types, LocalTypes >::type >::type container_; // typename boost::make_variant_over< // typename boost::mpl::copy< // LocalTypes, // boost::mpl::back_inserter<Types> // >::type // >::type container_; }; struct LocalType1 {}; struct LocalType2 {}; int main() { typedef boost::mpl::list< LocalType1, LocalType2 > Types; Foo<Types> foo; } 

Using mpl::joint_view (which I assume if this is the most efficient way to achieve this), I get the following error:

 /usr/local/include/boost/mpl/clear.hpp:29:7: error: implicit instantiation of undefined template 

Uncommenting another attempt using mpl::copy and replacing it with the original, the error will change:

 /usr/local/include/boost/mpl/aux_/push_back_impl.hpp:40:9: error: no matching function for call to 'assertion_failed' 

Interestingly, has the following comment :

 // should be instantiated only in the context of 'has_push_back_impl'; // if you've got an assert here, you are requesting a 'push_back' // specialization that doesn't exist. 

None of these errors makes any sense to me, like, w / r / t, firstly, I donโ€™t see which templates are not complete, and for the second, some kind of push_back specialization that I donโ€™t use?

+6
source share
1 answer

The problem is that boost::mpl::clear<> not implemented for joint_view ... so a huge compiler dump is completed with:

 /usr/local/include/boost/mpl/clear.hpp:29:7: error: implicit instantiation of undefined template 'boost::mpl::clear_impl<boost::mpl::aux::joint_view_tag>::apply<boost::mpl::joint_view<boost::mpl::list<InternalType1, InternalType2, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::mpl::list<LocalType1, LocalType2, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> > >' 

(I do not know how to format it correctly)

It may simply be an oversight in the library, or it is simply not clear which empty sequence type should be returned in this case. If you want to use joint_view , you will need to specify the clear_impl specialization somewhere:

 namespace boost { namespace mpl { template <> struct clear_impl<aux::joint_view_tag> { template <typename JV> struct apply { typedef list<> type; // since you're using list I figured // I would too. }; }; } } 

At the same time, your code compiles for me for both gcc and clang.

Alternatively, if adding stuff to namespace boost::mpl hits you like a little shady, but you still want to stick to list s, you can simply use insert_range :

 typename boost::make_variant_over< typename boost::mpl::insert_range< Types, typename boost::mpl::end<Types>::type, LocalTypes >::type >::type container_; 
+2
source

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


All Articles