Studying modern c++ design, looks like Typelist is a very important tool for
generic programming.
Could I find something like Typelist from boost? I found something like boost::mpl
but I didn't see anything like Nulltype defined in loki
Could boost::mpl replace the Typelist of loki?

Thanks

Recommended Answers

All 10 Replies

The Boost.MPL is a great tool for template meta-programming. It basically contains an entire compile-time implementation of the STL containers and algorithms. So, yes, there are plenty of alternatives to loki::Typelist. In MPL terms, these are Sequences. You can choose, like with STL containers, whether you want random-access or not, associative container or not, sorted or not, etc. It goes quite a bit beyond the Typelist implementation.

If you are reading Alexandrescu's book, the important thing is to learn the tricks of the trade, in template meta-programming. For actual feature-rich implementations and code that you can use, you should look towards Boost, the Boost.MPL in particular, and, of course, David Abraham's book on template meta-programming which, besides being a really good book on TMP, is almost an instruction manual to using the Boost.MPL.

Thanks a lot, I have a lot of questions about the TMP techniques on CH3
Do we have some good tools to navigate the deduction process of template?
I am not sure that my deduction about the codes are correct
To verify it, I would post the processes when I have time

Thanks

In most cases where typelists were used in old C++ (for example in tuple<>) , we do not need them any more - variadic templates would do the job better, and more efficiently too. As such, IMHO, libraries like Boost MPL would be rarely used; most of the verbose and somewhat intractable code in these libraries would eventually become thin wrappers over variadic parameter packs any way.

For example,

#include <tuple>

template< typename... TYPES > struct typelist {};

template< typename... TYPES > struct size {} ;
template< typename... TYPES > struct size< typelist<TYPES...> >
{ enum { value = sizeof...(TYPES) } ; } ;

template< typename T, typename... TYPES > struct push_front {} ;
template< typename T, typename... TYPES > struct push_front< T, typelist<TYPES...> >
{ typedef typelist< T, TYPES... > type ; } ;

template< typename... TYPES > struct pop_front {} ;
template< typename T, typename... TYPES > struct pop_front< typelist< T, TYPES... > >
{ typedef typelist<TYPES...> type ; } ;

template< unsigned int N, typename... TYPES > struct at {} ;
template< unsigned int N, typename... TYPES > struct at< N, typelist<TYPES...> >
{ typedef typename std::tuple_element< N, std::tuple<TYPES...> >::type type ; };

// .. etc

If these codes could work, than variadic template is much more powerful
than I could imagine.
It makes TMP become much more easier to learn, read, maintain and implement
Looks like C++11 really lower the learning curve of C++
standard committee really did a good job to let variadic template and other
helpful features become part of the standard.

With template variadic, We could expect that TMP and GP would become much more
popular than the old time.

When would visual c++ support variadic template?No matter what, there are still
many users are using visual c++.

I would keep studying modern c++ design, but would implement those TMP LIBS by
variadic template again.

Sorry, I am stuck at IndexOf when out of NullType
How could I make something like this come true?

IndexOf<double, Typelist<int, double, float> >::value == 1

Thanks

I found a solution from
htp://stackoverflow.com/questions/6032089/position-of-a-type-in-a-variadic-template-parameter-pack

template <class Tuple, class T, std::size_t Index = 0>
struct find_first;

template <std::size_t Index, bool Valid>
struct find_first_final_test
{
  enum { value = Index };
};

template <std::size_t Index>
struct find_first_final_test<Index, false>
{
  static_assert(Index == -1, "Type not found in find_first");
};

template <class Head, class T, std::size_t Index>
struct find_first<std::tuple<Head>, T, Index>
{
  enum { value = find_first_final_test<Index, boost::is_same<Head, T>::value>::value };
};

template <class Head, class ...Rest, class T, std::size_t Index>
struct find_first<std::tuple<Head, Rest...>, T, Index>
: public boost::conditional<
                            boost::is_same<Head, T>::value,
                            boost::integral_constant<std::size_t, Index>,
                            find_first<std::tuple<Rest...>, T, Index + 1>
                           >::type
{
};

void test_variadic_IndexOf()
{
  typedef std::tuple<char, int, short> T;
  std::cout << find_first<T, short>::value << '\n';
}

Do you have other solutions?
Thanks

Or maybe this:

template <class Tuple, class T, std::size_t Index = 0>
struct find_first;

template <class T, std::size_t Index>
struct find_first< std::tuple<>, T, Index>
{
  static_assert(false, "Type not found in find_first");
};

template <class Head, class... Rest, class T, std::size_t Index>
struct find_first< std::tuple<Head, Rest...>, T, Index> : 
  public find_first< std::tuple<Rest...>, T, Index + 1> { };

template <class Head, class... Rest, std::size_t Index>
struct find_first< std::tuple<Head, Rest...>, Head, Index>
: public boost::mpl::size_t<Index> { };

void test_variadic_IndexOf()
{
  typedef std::tuple<char, int, short> T;
  std::cout << find_first<T, short>::value << '\n';
}

> I found a solution from
> htp://stackoverflow.com/questions/6032089/position-of-a-type-in-a-variadic-template-parameter-pack

Needlessly over-elaborate, isn't it? This would suffice:

template< typename T, typename U, int N = 0 > struct indexof ;

template< typename T, int N > struct indexof< T, typelist<>, N > { enum { value = -1 } ; };

template< typename T, typename FIRST, typename ...REST, int N >
struct indexof< T, typelist<FIRST,REST...>, N >
            : std::conditional< std::is_same<T,FIRST>::value,
                                std::integral_constant<int,N>,
                                indexof< T, typelist<REST...>, N+1 > >::type {} ;

All that we need to do is recursively unpack the parameters one by one, keeping a count of how many have been unpacked so far, and ending the recursion if the type has been found (or the last parameter has been unpacked).

Thank you very much, both of yours answers make me know more about variadic template
explicitly the use of "tuple<>", so that is the other way to instead the NullType
being used by "modern c++ design".

Even TMP is very powerful, it is only supported by C++ AFAIK, except of the skills
of recursive, what else could we learn from TMP?

Thanks

>>what else could we learn from TMP?

TMP is a form of pure functional programming (no mutable data, no side-effects). So, in some sense you learn, from TMP, a very fundamental form of programming. But, academics aside, what's more important with TMP is what you can learn to use it for. Expression templates come to mind, among other things like concept-maps or all sorts of applications of tuples (or typelists).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.