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;
}
};
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;
}