How do I loop over a boost MPL list of non-default constructed classes?

↘锁芯ラ 提交于 2019-12-04 11:36:51
Sam Kellett

I've solved this by adding a type wrapper struct, like the one seen in Boost.Hana. I added this to the great idea found in this comment that mentions using boost::mpl::transform to add this wrapper type to each item in the list automatically.

The following details my solution:

template <typename T>
struct type_
{
  using type = T;
};

template <typename T>
struct add_type_wrapper
{
  using type = type_<T>;
};

Using these two new types, I altered the type_printer functor to look like so:

struct type_printer
{
  template <typename T>
  void operator()(T)
  {
    using type_t = typename T::type;
    print<type_t>();
  }
};

And the boost::mpl::for_each call in main now looks like this:

using boost::mpl::_1;
using wrapped_list = boost::mpl::transform<type_list, add_type_wrapper<_1>>::type;
boost::mpl::for_each<wrapped_list>(type_printer());

Thanks for your help guys, I think this is a really nice and elegant solution.

You can also add one level of indirection to items in your type list like this:

template <typename T>
struct type_ref
{
  typedef T type;
}

struct type_printer
{
  template <typename T>
  void operator()(T)
  {
    print<T>();
  }
  template <typename T>
  void operator()(type_ref<T>)
  {
    print<T>();
  }
};

int main()
{
  typedef boost::mpl::list<
    one,
    two,
    three,
    four,
    type_ref<five>
  >::type type_list;

  boost::mpl::for_each<type_list>(type_printer());
}

You may do yourself something like:

namespace detail {

    template <typename Tuple>
    structure my_for_each_t;

    template <typename... Ts>
    structure my_for_each_t<boost::mpl::list<Ts...>>
    {
        template <typename F>
        void operator()(F f) const
        {
             initializer_list<int>{(static_cast<void>(f<Ts>()), 0)...};
        }
    };

}

template <typename Tuple, typename F>
void my_for_each(F f)
{
    detail::my_for_each_t<Tuple>()(f);
}

Or transform your list to add pointer to the type, and change your type_printer:

struct type_printer
{
  template <typename T>
  void operator()(T*) // pointer added.
  {
    print<T>();
  }
};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!