CodeBlanks Logo Icon CodeBlanks

Modern C++

Write data processing with modern C++ (concepts, ranges).

Data processing with modern C++

In this lesson we add the process_data method to Framework. This method is a template constrained with concepts and does chained filtering with ranges.

Example: template<std::integral T> int process_data(const std::vector<T>& data). Body: for (auto x : data | std::views::filter([](T v) { return v > 0; })) sum += x;. This filters positive values and sums them. The std::integral constraint accepts only integer types; std::views::filter produces a lazy view. We take the previous lesson's skeleton and add this method.

Chaining with ranges

Ranges lets you chain algorithms with the | operator. data | std::views::filter(pred) filters the data and gives a lazy view.

Example: data | std::views::filter([](T v) { return v > 0; }). This drops negative values. You then sum the result with a for loop. In old C++ you would need an intermediate vector with std::copy_if; with ranges there is no intermediate variable. This means more readable and more efficient code. The output accumulates below the previous lesson's "Project ready" line.

Practice Add the process_data method

Add template<std::integral T> int process_data(const std::vector<T>& data) to Framework. Its body should filter with data | std::views::filter([](T v) { return v > 0; }) and sum. In run define std::vector<int> data{1, -2, 3}; and print with std::cout << "sum: " << process_data(data);.

Starter code

main.cpp
#include <iostream>
#include <string>
#include <vector>
#include <ranges>
#include <algorithm>
#include <concepts>

class Framework {
public:
    int run();
    // Add the process_data template method (with integral concept)
};

int Framework::run() {
    std::cout << "Project ready" << std::endl;
    // Call process_data and print the result
    return 0;
}

int main() {
    Framework fw;
    fw.run();
    return 0;
}

Sample solution

main.cpp
#include <iostream>
#include <string>
#include <vector>
#include <ranges>
#include <algorithm>
#include <concepts>

class Framework {
public:
    int run();
    template<std::integral T>
    int process_data(const std::vector<T>& data);
};

template<std::integral T>
int Framework::process_data(const std::vector<T>& data) {
    int sum = 0;
    for (auto x : data | std::views::filter([](T v) { return v > 0; })) {
        sum += x;
    }
    return sum;
}

int Framework::run() {
    std::cout << "Project ready" << std::endl;
    std::vector<int> data{1, -2, 3};
    std::cout << "sum: " << process_data(data);
    return 0;
}

int main() {
    Framework fw;
    fw.run();
    return 0;
}

Expected output

Project ready
sum: 4

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Match each concept to its description

Term Meaning
std::integral Integer constraint
std::views::filter Filter view
ranges Chained algorithms
concept Type constraint

2 the views filter

Question
data | std::____::filter([](int v) { return v > 0; })
Answer
data | std::views::filter([](int v) { return v > 0; })

Explanation: std::views::filter produces a filter view.

3 What does std::ranges provide?

  • Exception safety
  • Multithreading
  • Memory management
  • Chaining composition of algorithms Correct answer

Explanation: ranges lets you chain algorithms with |.

All lessons in Advanced