Sam Kellett
Sam Kellett

Reputation: 1347

How do I fold an MPL type list into a variadic container?

If I have a list of types, how can I get a type with that list as it's variadic parameters?

In other words, I want to go from this:

boost::mpl::list<foo, bar, baz, quux>

To:

types<foo, bar, baz, quux>

(Order not important)

Here's my attempt using fold:

typedef boost::mpl::list<foo, bar, baz, quux> type_list;

template <typename... Ts>
struct types {};

template <template <typename... Ts> class List, typename T>
struct add_to_types {
  typedef types<T, typename Ts...> type;
};

typedef boost::mpl::fold<
  type_list,
  types<>,
  add_to_types<boost::mpl::_1, boost::mpl::_2>
>::type final_type;

Unfortunately this gives me errors regarding the placeholders:

error: type/value mismatch at argument 1 in template parameter list for 'template<template<class ... Ts> class List, class T> struct add_to_types'
error:   expected a class template, got 'mpl_::_1 {aka mpl_::arg<1>}'
error: template argument 3 is invalid
error: expected initializer before 'final_type'

Upvotes: 2

Views: 412

Answers (1)

Pradhan
Pradhan

Reputation: 16737

The problem is that types<Ts...> is a class and not a class template. However, your add_to_types expects a class template as the first argument. To get your fold expression to work, you could change add_to_types to take two class arguments and specialize add_to_types for the case of the first argument being types<Ts...>:

template <typename Seq, typename T>
struct add_to_types;

template <typename T, typename... Ts>
struct add_to_types<types<Ts...>, T>
{
  typedef types<T, Ts...> type;
};

Upvotes: 3

Related Questions