Search code examples
c++variadic-templatesvariadic-functions

Variadic templates and function objects


Lets say that we have two function objects that take an int and return a boolean:

struct EvenNumber {
  bool operator()(int const num) const {
   return num % 2 == 0;
  }
}

struct GreaterThenFive {
  bool operator()(int const num) const {
    return num > 5;
  }
}

now let's say that we have a function that takes a vector and a variadic template of filters. The function should return a new vector containing only those elements from the original vector that satisfy filtering operations:

template <typename... Filters>
std::vector<int> filter_out(std::vector<int> const& vec, Filters&&... filters) {
  std::vector<int> result;

  for (int const num : vec) {
    if (std::forward<filters>(filters)(num)...) {
      result.push_back(num);
    }
  }

  return result;
}

But this doesn't work with unexpected token ...; expected ). do we need fold expression here? how should the syntax look if we want to perform all filtering operations on all numbers of the original vector?

calling code can look like this:

auto result = filter_out({1, 2, 3, 4, 5, 6, 7}, EvenNumber{}, GreaterThenFive{});

Solution

  • You can't just call each filter on the argument, you also need to make a disjunction of the result of all the filters.

    if ((std::forward<Filters>(filters)(num) && ...)) {
                                          // ^^  ALL conditions must be satisfied
    

    Also, the argument to forward needs to be the type Filters, not the value filters.

    Here's a demo.