Standard Library Views

Differences between std::views::filter() and std::remove_if()

What are the differences between std::views::filter() and std::remove_if() in terms of functionality and performance?

Abstract art representing computer programming

std::views::filter() and std::remove_if() serve different purposes and have different performance characteristics.

std::views::filter() has the following characteristics:

  • Purpose: Creates a view that includes only the elements that satisfy a given predicate.
  • Non-Owning: Does not modify the original container. It simply provides a filtered view.
  • Lazy Evaluation: Elements are evaluated on-demand, which can be more efficient if you only need to process part of the range.

The following program uses std::views::filter() to create a view of an underlying std::vector. The view contains only the odd numbers within the vector, but the vector itself is not modified:

#include <iostream>
#include <ranges>
#include <vector>

int main() {
  std::vector<int> Numbers{1, 2, 3, 4, 5};

  auto FilteredView = Numbers
    | std::views::filter([](int x) {
    return x % 2 == 1;
  });

  for (int Num : FilteredView) {
    std::cout << Num << ", ";
  }
}
1, 3, 5,

std::remove_if() has these characteristics:

  • Purpose: Rearranges the elements in the container so that the elements that do not satisfy the predicate are moved to the beginning, and returns an iterator to the new end.
  • Owning: Modifies the original container. You often need to erase the elements that do not satisfy the predicate afterward.
  • Eager Evaluation: Processes all elements at once, which can be less efficient if only part of the range is needed.

The following program uses std::remove_if() to move the even numbers to the end of a std::vector.

It then uses the erase() method to remove those elements from the container.

As a result, only the odd numbers remain in our std::vector:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
  std::vector<int> Numbers{1, 2, 3, 4, 5};

  auto it = std::remove_if(
    Numbers.begin(), Numbers.end(),
    [](int x) { return x % 2 == 0; }
  );

  Numbers.erase(it, Numbers.end());

  for (int Num : Numbers) {
    std::cout << Num << ", ";
  }
}
1, 3, 5,

Performance Comparison

  • Memory: std::views::filter() uses less memory since it doesn’t create a new container but instead provides a view. std::remove_if() may require extra memory if elements are erased and the container is resized.
  • Speed: std::views::filter() can be faster for partial processing due to lazy evaluation. std::remove_if() processes all elements eagerly, which may be less efficient for large datasets.
  • Use Case: Use std::views::filter() when you need a non-modifying, lazy-evaluated view. Use std::remove_if() when you need to modify the container directly and remove elements.

Understanding these differences helps choose the right tool for specific use cases, balancing performance and functionality needs.

Answers to questions are automatically generated and may not have been reviewed.

Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved