Search code examples
c++templatesc++11boostboost-mpl

Is there a way to recover original template template class enbeded in boost mpl quote?


I quoted a template class to put it into a mpl::vector doing this:

boost::mpl::vector<int, boost::mpl::quote2<std::pair>>

Then, I obtained the 2nd element like this:

using A=typename boost::mpl::at<T, boost::mpl::int_<2>>::type;

I need now to pass the original template class to a class like this:

template<class A, template<class, class> class C>
class B{
    C<A, B*> _c;
};

I'm tried using apply or bind, but couldn't find the way to make B accept the second parameter.

I get errors of the kind:

error: template argument for template template parameter must be a class template or type alias template

edit:

Example code:

#include <boost/mpl/vector.hpp>
#include <boost/mpl/quote.hpp>
#include <boost/mpl/at.hpp>

template<class, class> class A{};
template<class A, template<class, class> class C>
class B{
    C<A, B*> _c;
};
using T=boost::mpl::vector<int, boost::mpl::quote2<A>> ;
using T1=typename boost::mpl::at<T, boost::mpl::int_<0>>::type;
using T2=typename boost::mpl::at<T, boost::mpl::int_<1>>::type;

int main(){
    B<T1, T2> b;
    return 0;
}

I get:

error: template argument for template template parameter must be a class template or type alias template B<T1, T2> b;

Solution

  • MPL is still largely a C++03 lib AFAIK and you're trying to make it generate something that didn't conceptually exist before C++11. I suspect that having quote work in that case is a coincidence of syntax rather than intended functionality.

    The following code compiles successfully in VC2013:

    #include <boost/mpl/vector.hpp>
    #include <boost/mpl/quote.hpp>
    #include <boost/mpl/apply.hpp>
    #include <boost/mpl/at.hpp>
    
    template<class, class> class A{};
    template<class A, template<class, class> class C>
    class B{
        C<A, B*> _c;
    };
    using T = boost::mpl::vector < int, boost::mpl::quote2<A> > ;
    using T1 = boost::mpl::at<T, boost::mpl::int_<0>>::type;
    using T2 = boost::mpl::at<T, boost::mpl::int_<1>>::type;
    
    template<typename X1, typename X2>
    using TT2 = typename boost::mpl::apply<T2, X1, X2>::type;
    
    int main(int argc, char* argv[])
    {
        B<T1, TT2> b;
        return 0;
    }