c++boostc++20boost-mp11

Get parameter pack from boost mp_list


I'm struggling to filter a parameter pack while keeping it as a parameter pack.

Using boost::mp11, I have created a filtered mp_list of the parameter pack, but I don't know how to then use this list in a fold expression.

template <typename... MyTypes>
class Foo
{
  public:
    static std::vector<Bar> getBars()
    {
      std::vector<Bar> bars;
      using filtered = boost::mp11::mp_filter<is_barable, boost::mp11::mp_list<MyTypes...>>;
      (bars.push_back(filtered::bar()), ...);
      return bar;
    }
};

Assuming is_barable is std::true_type when MyTypes has an appropriate static Bar bar(); method, and is std::false_type otherwise.

The above does not compile because filtered isn't seen as a parameter pack which can be expanded. Is there a way to take a parameter pack from the mp_list?

So far my best attempt is to use an intermediate lambda template which is pretty ugly IMO, but I can't manage it any other way:

template <typename... MyTypes>
class Foo
{
  public:
    static std::vector<Bar> getBars()
    {
      std::vector<Bar> bars;
      using filtered = boost::mp11::mp_filter<is_barable, boost::mp11::mp_list<MyTypes...>>;

      auto foo = [&bars]<typename... Ts>(boost::mp11::mp_list<Ts...>)
      {
        (bars.push_back(Ts::bar()), ...);
      };
      foo(filtered{});

      return bar;
    }
};

Solution

  • You can use mp_for_each to iterate over filtered types

    static std::vector<Bar> getBars()
    {
      std::vector<Bar> bars;
      using filtered = boost::mp11::mp_filter<is_barable, boost::mp11::mp_list<MyTypes...>>;
      boost::mp11::mp_for_each<filtered>([&]<class T>(T){
        bars.push_back(T::bar());
      });
      return bars;
    }