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