Search code examples
c++templatesboostboost-mpl

Selecting type with mpl::if_ and integer template parameter


The following code works on Visual Studio 2005, but gives me a compiler error when compiled with g++ 4.4.5:

#include <boost/mpl/if.hpp>
#include <boost/mpl/bool.hpp>

template<int X> struct A
{
    void f() {
        typedef boost::mpl::if_<boost::mpl::bool_<X == 1>, int, bool>::type Type;
    }
};

This is the error I get:

main.cpp: In member function ‘void A<X>::f()’:
main.cpp:12: error: too few template-parameter-lists

What's wrong with the code? If I replace the templated X with a hard coded number, the code compiles just fine. I've also tried wrapping X with a mpl::int_ type but without any success.

Thanks!


Solution

  • You need the typename keyword:

    typedef typename                   // <-- Here
        boost::mpl::if_<
            boost::mpl::bool_<X == 1>,
            int,
            bool
        >::type Type;
    

    The compiler cannot be sure that mpl::if_<...>::type is a type, since it does not know the value of X: if_ could be specialized for certain parameters and include a type member which is not a type, for instance:

    //Silly if_ specialization
    template <typename Then, typename Else>
    struct if_<void, Then, Else>
    {
        int type;
    };
    

    Therefore, you need to explicitly tell the compiler that ::type denotes a type, with the typename keyword.

    See an in-depth explanation here: Where and why do I have to put the template and typename keywords.