Question
How to Initialize std::vector with Hardcoded Values in C++
Question
I can create an array and initialize it like this:
int a[] = {10, 20, 30};
How can I create a std::vector and initialize it in a similarly clean and elegant way?
The best approach I currently know is:
std::vector<int> ints;
ints.push_back(10);
ints.push_back(20);
ints.push_back(30);
Is there a better way to initialize a std::vector with hardcoded elements?
Short Answer
By the end of this page, you will understand the simplest ways to initialize a std::vector with fixed values in C++, when to use each approach, and how modern C++ makes vector initialization much cleaner than repeated push_back calls.
Concept
std::vector is a dynamic array in C++. Unlike a built-in array, it can grow and shrink at runtime. Because of that flexibility, C++ provides several ways to create and fill a vector.
When you already know the values you want to store, the most readable approach in modern C++ is usually list initialization using braces:
std::vector<int> ints = {10, 20, 30};
or simply:
std::vector<int> ints{10, 20, 30};
This works because std::vector supports initializer lists. An initializer list lets you pass a fixed set of values directly when constructing the vector.
This matters in real programming because:
- it makes code shorter and easier to read
- it reduces repetitive
push_backcalls - it clearly shows the vector's initial contents
- it avoids accidental mistakes from forgetting an element or adding them in multiple places
Before C++11, developers often had to use less elegant approaches, such as creating an array first and copying its contents into the vector. In modern C++, brace initialization is the standard beginner-friendly solution.
Mental Model
Think of a std::vector like a resizable shopping basket.
- A built-in array is like a fixed egg carton: its size is decided immediately.
- A
std::vectoris like a basket that can hold more items later.
If you already know the starting items, brace initialization is like filling the basket all at once:
std::vector<int> ints{10, 20, 30};
Using repeated push_back is like putting items in one by one after picking up the basket. That works, but it is more verbose when the items are already known.
Syntax and Examples
The most common ways to initialize a std::vector are below.
1. Initialize with hardcoded values using braces
#include <vector>
std::vector<int> nums{10, 20, 30};
This is the cleanest modern C++ approach.
You may also see:
std::vector<int> nums = {10, 20, 30};
Both forms are valid.
2. Initialize with repeated copies of one value
std::vector<int> nums(3, 100);
This creates:
{100, 100, 100}
Be careful: this is different from brace initialization.
3. Construct from an array
int a[] = {10, 20, 30};
std::vector<int> nums(std::begin(a), std::end(a));
This is useful when you already have an array and want to copy its contents into a vector.
Full example
#include <iostream>
#include <vector>
int main() {
std::vector<int> ints{10, 20, 30};
for (int value : ints) {
std::cout << value << ' ';
}
}
Output:
10 20 30
Why this is better than repeated push_back
Instead of this:
std::vector<int> ints;
ints.push_back(10);
ints.push_back(20);
ints.push_back(30);
You can write this:
std::vector<int> ints{10, 20, 30};
It is shorter, clearer, and directly shows the initial contents.
Step by Step Execution
Consider this example:
#include <vector>
int main() {
std::vector<int> ints{10, 20, 30};
return 0;
}
Here is what happens step by step:
- The program reaches
std::vector<int> ints{10, 20, 30}; - A vector named
intsis created. - The type inside the vector is
int. - The brace list
{10, 20, 30}is passed to the vector constructor. - The vector stores three elements in order:
ints[0]becomes10ints[1]becomes20ints[2]becomes30
- The vector size becomes
3.
You can verify that with this traceable example:
#include <iostream>
#include <vector>
int main() {
std::vector<int> ints{10, 20, 30};
std::cout << "Size: " << ints.size() << '\n';
std::cout << "First: " << ints[0] << '\n';
std::cout << "Second: " << ints[1] << '\n';
std::cout << "Third: " << ints[2] << '\n';
}
Output:
Size: 3
First: 10
Second: 20
Third: 30
Real World Use Cases
Hardcoded vector initialization is common when a program starts with a known set of values.
Common examples
-
Menu choices
std::vector<std::string> options{"start", "settings", "quit"}; -
Allowed status codes
std::vector<int> validCodes{200, 201, 204}; -
Default configuration values
std::vector<double> thresholds{0.25, 0.5, 0.75}; -
Test data in unit tests
std::vector<int> input{1, 2, 3, 4, 5}; -
Coordinate or sample data in small programs
std::vector<int> points{10, 15, 22, 18};
In all of these cases, brace initialization is useful because the starting values are known in advance.
Real Codebase Usage
In real projects, developers often use vector initialization in a few common patterns.
1. Default data setup
A vector may be created with default values near the point of declaration:
std::vector<std::string> roles{"admin", "editor", "viewer"};
This keeps the code readable and avoids scattered push_back calls.
2. Test fixtures and sample input
In tests, short inline vectors are very common:
std::vector<int> expected{2, 4, 6};
This makes expected values easy to compare.
3. Guarded setup before processing
Developers may initialize a vector and then validate it:
std::vector<int> ports{80, 443, 8080};
if (ports.empty()) {
return;
}
4. Copying from existing ranges
When values come from arrays or other containers, range constructors are often used:
int raw[] = {10, 20, 30};
std::vector<int> nums(std::begin(raw), std::end(raw));
5. Building incrementally when values are not known yet
If values depend on logic, push_back is still appropriate:
std::vector<int> nums;
for (int i = 0; i < 3; ++i) {
nums.push_back(i * 10);
}
So in real codebases, brace initialization is preferred for known values, and push_back is used when values are discovered during execution.
Common Mistakes
Here are common mistakes beginners make when initializing std::vector.
1. Confusing parentheses with braces
These two do different things:
std::vector<int> a(3, 10);
std::vector<int> b{3, 10};
a becomes:
{10, 10, 10}
b becomes:
{3, 10}
How to avoid it
- Use braces when listing explicit elements.
- Use parentheses when calling a constructor with size and value.
2. Forgetting to include the header
Broken code:
std::vector<int> nums{1, 2, 3};
This will fail if you forget:
#include <vector>
3. Using old-style approaches unnecessarily
Less clear:
std::vector<int> nums;
nums.push_back(10);
nums.push_back(20);
nums.push_back(30);
Better when values are already known:
std::vector<int> nums{10, 20, 30};
4. Assuming vectors work exactly like arrays
A vector is not a built-in array. It manages memory dynamically and has member functions like:
size()push_back()empty()
5. Using initializer-list syntax in an older C++ standard
Brace initialization for vectors requires modern C++ support, typically C++11 or later.
How to avoid it
Compile with a modern standard, for example:
g++ -std=c++11 file.cpp
or newer, such as C++17 or C++20.
Comparisons
Here is a comparison of common ways to create a std::vector.
| Approach | Example | Best for | Notes |
|---|---|---|---|
| Brace initialization | std::vector<int> v{10, 20, 30}; | Known hardcoded values | Most readable in modern C++ |
| Copy-list initialization | std::vector<int> v = {10, 20, 30}; | Known hardcoded values | Also common and clear |
| Repeated value constructor | std::vector<int> v(3, 10); | Same value repeated | Creates 3 elements, each 10 |
| Range constructor | std::vector<int> v(begin, end); | Copying from arrays or other containers | Useful when data already exists elsewhere |
push_back repeatedly | v.push_back(10); | Values discovered later | More verbose for fixed values |
Array vs vector
| Feature | Built-in array | std::vector |
|---|---|---|
| Size changes at runtime | No | Yes |
| Can use brace initialization | Yes | Yes |
Has size() method | No | Yes |
| Convenient for hardcoded values | Yes | Yes |
| Safer and more flexible for general use | Less | More |
Braces vs parentheses for vector
| Syntax | Meaning |
|---|---|
std::vector<int> v{1, 2, 3}; | Elements are 1, 2, 3 |
std::vector<int> v(3, 2); | Three elements, all equal to 2 |
Cheat Sheet
#include <vector>
Initialize with hardcoded values
std::vector<int> v{10, 20, 30};
std::vector<int> v = {10, 20, 30};
Initialize with repeated value
std::vector<int> v(3, 5); // {5, 5, 5}
Copy from an array
int a[] = {10, 20, 30};
std::vector<int> v(std::begin(a), std::end(a));
Add items later
std::vector<int> v;
v.push_back(10);
v.push_back(20);
Key rule
- Use braces for explicit element lists.
- Use parentheses for constructor arguments like size and default value.
Common trap
std::vector<int> a(3, 10); // {10, 10, 10}
std::vector<int> b{3, 10}; // {3, 10}
Best modern answer to the original question
std::vector<int> ints{10, 20, 30};
FAQ
Can I initialize a std::vector like an array in C++?
Yes. In modern C++, you can use brace initialization:
std::vector<int> v{10, 20, 30};
Is std::vector<int> v = {1, 2, 3}; valid?
Yes. This is valid C++ and is a common way to initialize a vector with fixed values.
What is the difference between vector<int>(3, 10) and vector<int>{3, 10}?
vector<int>(3, 10) creates three elements, each equal to 10.
vector<int>{3, 10} creates two elements: 3 and 10.
Should I use push_back or brace initialization?
Use brace initialization when the values are already known. Use push_back when values are produced later by logic, loops, input, or function results.
Does this require C++11?
Yes, initializer-list vector syntax is part of modern C++ and is available from C++11 onward.
Can I initialize a vector from an existing array?
Yes:
int a[] = {10, 20, 30};
std::vector<int> v(std::begin(a), std::end(a));
Is brace initialization the most readable option?
Usually yes, especially for short fixed lists of values.
Mini Project
Description
Build a small C++ program that stores a list of hardcoded exam scores in a std::vector, then prints them and calculates the total. This demonstrates clean vector initialization with brace syntax and basic iteration over vector elements.
Goal
Create and use a std::vector<int> initialized with hardcoded values, then process its contents.
Requirements
- Create a
std::vector<int>with at least five hardcoded scores using brace initialization. - Print each score to the console.
- Calculate the sum of all scores.
- Print the total and the number of scores.
Keep learning
Related questions
Advantages of Brace Initialization in C++
Learn why C++ brace initialization is often clearer and safer than other object initialization styles, with examples and common pitfalls.
Basic Rules and Idioms for Operator Overloading in C++
Learn the core rules, syntax, and common idioms for operator overloading in C++, including member vs non-member operators.
C++ Aggregates, Trivial Types, Trivially Copyable Types, and PODs Explained
Learn what aggregates, trivial types, trivially copyable types, and PODs mean in C++, how they differ, and why they matter.