Modifying Sequence Elements in C++ with Fill, Generate, and Iota Algorithms

std::fill

The std::fill algorithm assigns a specific value to every element within a defined range. It requires two iterators defining the range's bounds and the value to be assigned. This is particularly useful for re-initializing buffers or resetting data structures.

#include <iostream>
#include <vector>
#include <algorithm> // Contains std::fill

int main() {
    // Initialize a vector of capacity 6
    std::vector<int> buffer(6);

    // Assign value 255 to all elements in the range
    std::fill(buffer.begin(), buffer.end(), 255);

    // Display the modified contents
    for (const auto& item : buffer) {
        std::cout << item << " ";
    }
    std::cout << "\n";

    return 0;
}

Output:

255 255 255 255 255 255

std::fill_n

When the exact number of elements to modify is known, std::fill_n is an efficient alternative. It accepts an iterator to the starting position, a count representing the number of elements, and the value.

#include <iostream>
#include <deque>
#include <algorithm>

int main() {
    std::deque<double> measurements = {1.5, 2.5, 3.5, 4.5, 5.5};

    // Overwrite the first 2 elements with 0.0
    std::fill_n(measurements.begin(), 2, 0.0);

    for (auto val : measurements) {
        std::cout << val << " ";
    }
    std::cout << "\n";

    return 0;
}

Output:

0 0 3.5 4.5 5.5

std::generate

To populate a range with values calculated dynamically, std::generate is used. Unlike fill, which uses a constant value, this algorithm calls a provided generator function for each element in the range.

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

// Generator function providing sequential squares
int next_square() {
    static int current = 1;
    int result = current * current;
    ++current;
    return result;
}

int main() {
    std::vector<int> squares(4);

    // Fill the vector using the generator function
    std::generate(squares.begin(), squares.end(), next_square);

    for (auto v : squares) {
        std::cout << v << " ";
    }
    std::cout << "\n";

    return 0;
}

Output:

1 4 9 16

std::generate_n

This variant limits the generation process to the first n elements starting from the given iterator. The function signature includes an output iterator, a size count, and a generator function object.

#include <iostream>
#include <list>
#include <algorithm>

int main() {
    std::list<int> data_series(5);

    // Lambda to generate multiples of 10
    int multiplier = 1;
    auto gen_ten = [&multiplier]() { return 10 * multiplier++; };

    // Generate values for the first 3 elements
    std::generate_n(data_series.begin(), 3, gen_ten);

    for (auto elem : data_series) {
        std::cout << elem << " ";
    }
    std::cout << "\n";

    return 0;
}

Output:

10 20 30 0 0

std::iota

Defined in the <numeric> header, std::iota fills a range with sequentially increasing values, starting from a specified initial value and incrementing using operator++.

#include <iostream>
#include <vector>
#include <numeric> // Required for std::iota

int main() {
    std::vector<int> identifiers(6);

    // Fill with 100, 101, 102, ...
    std::iota(identifiers.begin(), identifiers.end(), 100);

    for (int id : identifiers) {
        std::cout << id << " ";
    }
    std::cout << "\n";

    return 0;
}

Output:

100 101 102 103 104 105

Tags: C++ STL algorithms Generic Programming

Posted on Sat, 18 Jul 2026 17:13:29 +0000 by melvincr