C++ Algorithm Generate | "Generation Algorithm" Guide
이 글의 핵심
std::generate, fill, iota: fill ranges from functors or sequences—test data, indices, and initialization patterns in C++.
Generation-style algorithms fill a range either with a constant (fill, fill_n) or with values produced by a callable (generate, generate_n). std::iota (in <numeric>) assigns a increasing sequence—handy for indices and test data. Unlike copying from another container, you must already have storage (sized container or reserved capacity with an output iterator); these algorithms do not insert elements by themselves unless you use something like std::back_inserter with a generator that respects container growth (unusual for fill).
Generation algorithms
Use fill when every element should be the same; use generate when each position needs a distinct value from a function (random IDs, synthetic data, counters).
#include <algorithm>
#include <vector>
std::vector<int> v(5);
// Fill with a value
std::fill(v.begin(), v.end(), 42);
// {42, 42, 42, 42, 42}
// Generate with a function
std::generate(v.begin(), v.end(), []() {
return rand() % 100;
});
fill and fill_n
fill sets every element in [first, last) to a value. fill_n writes n values starting at first—ensure there is room for n elements or you invoke undefined behavior.
#include <algorithm>
std::vector<int> v(10);
// Fill all elements with 0
std::fill(v.begin(), v.end(), 0);
// Fill only part of the range
std::fill(v.begin(), v.begin() + 5, 1);
// {1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
// fill_n
std::fill_n(v.begin(), 3, 2);
// {2, 2, 2, 1, 1, 0, 0, 0, 0, 0}
Practical Examples
Example 1: generate
#include <algorithm>
#include <vector>
#include <random>
int main() {
std::vector<int> v(10);
std::mt19937 gen{std::random_device{}()};
std::uniform_int_distribution<> dist{1, 100};
// Generate random numbers
std::generate(v.begin(), v.end(), [&]() {
return dist(gen);
});
for (int x : v) {
std::cout << x << " ";
}
}
Example 2: iota
#include <numeric>
#include <vector>
int main() {
std::vector<int> v(10);
// Generate sequential values
std::iota(v.begin(), v.end(), 1);
for (int x : v) {
std::cout << x << " "; // 1 2 3 4 5 6 7 8 9 10
}
}
Example 3: Counter
#include <algorithm>
class Counter {
int count = 0;
public:
int operator()() {
return count++;
}
};
int main() {
std::vector<int> v(10);
std::generate(v.begin(), v.end(), Counter{});
for (int x : v) {
std::cout << x << " "; // 0 1 2 3 4 5 6 7 8 9
}
}
Example 4: Initialization
#include <algorithm>
#include <vector>
struct Point {
int x, y;
};
int main() {
std::vector<Point> points(5);
int id = 0;
std::generate(points.begin(), points.end(), [&]() {
return Point{id++, id * 10};
});
for (const auto& p : points) {
std::cout << "(" << p.x << ", " << p.y << ") ";
}
}
Generation Algorithms
// Fill with a value
std::fill(begin, end, value)
std::fill_n(begin, n, value)
// Generate with a function
std::generate(begin, end, func)
std::generate_n(begin, n, func)
// Generate sequential values
std::iota(begin, end, value) // <numeric>
Common Issues
Issue 1: Size
std::vector<int> v;
// ❌ Size is 0
// std::fill(v.begin(), v.end(), 42); // Does nothing
// ✅ Specify size
v.resize(10);
std::fill(v.begin(), v.end(), 42);
Issue 2: Capture
int counter = 0;
std::vector<int> v(10);
// ✅ Capture by reference
std::generate(v.begin(), v.end(), [&]() {
return counter++;
});
// ❌ Capture by value
std::generate(v.begin(), v.end(), [=]() mutable {
return counter++; // Modifies a copy
});
Issue 3: Random Numbers
std::vector<int> v(10);
// ❌ rand() (C-style)
std::generate(v.begin(), v.end(), []() {
return rand() % 100;
});
// ✅ C++11 random
std::mt19937 gen{std::random_device{}()};
std::uniform_int_distribution<> dist{0, 99};
std::generate(v.begin(), v.end(), [&]() {
return dist(gen);
});
Issue 4: Performance
// fill: Optimized
std::fill(v.begin(), v.end(), 0);
// generate: Function call overhead
std::generate(v.begin(), v.end(), []() { return 0; });
// Use fill for simple values
Usage Patterns
// 1. Fixed value
std::fill(v.begin(), v.end(), 0);
// 2. Sequential values
std::iota(v.begin(), v.end(), 1);
// 3. Random numbers
std::generate(v.begin(), v.end(), randomFunc);
// 4. Conditional copy
std::copy_if(src.begin(), src.end(), dst.begin(), pred);
FAQ
Q1: What is fill?
A: Filling with a value.
Q2: What is generate?
A: Generating values using a function.
Q3: What is iota?
A: Generating sequential values.
Q4: What is copy_if?
A: Copying elements that satisfy a condition.
Q5: What about performance?
A: fill is faster than generate.
Q6: Recommended resources?
A:
- “Effective STL”
- “C++ Primer”
- cppreference.com
Related Posts (Internal Links)
Here are other posts connected to this topic:
- C++ STL algorithms — English series hub
- C++ Algorithm Count | “Count Algorithm” Guide
- C++ Algorithm Reverse | “Reverse Algorithm” Guide
- C++ Algorithm Replace | “Replace Algorithm” Guide
Practical Tips
Tips you can apply immediately in your projects.
Debugging Tips
- Check compiler warnings first when issues arise.
- Reproduce the issue with simple test cases.
Performance Tips
- Avoid premature optimization without profiling.
- Set measurable performance goals first.
Code Review Tips
- Anticipate common feedback during code reviews.
- Follow your team’s coding conventions.
Practical Checklist
Things to verify when applying this concept in real-world scenarios.
Before Writing Code
- Is this the best approach for solving the problem?
- Can team members understand and maintain this code?
- Does it meet performance requirements?
While Writing Code
- Have you resolved all compiler warnings?
- Have you considered edge cases?
- Is error handling appropriate?
During Code Review
- Is the intent of the code clear?
- Are there sufficient test cases?
- Is the code documented?
Use this checklist to reduce mistakes and improve code quality.
Keywords Covered in This Post (Related Search Terms)
C++, algorithm, generate, fill, STL — search for these terms to find relevant content.