Language[lang]
Struct in C++: declare, initialize and use one
- Section
- Language [lang]
- Standard
- C++17
- Compilers
- MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2, Clang 23.1 (libc++)
- Published
- Length
- 6 min read
In this answer7 clauses
Abstract
A struct in C++ is a type that groups several named values, its members, under one name: declare struct Point { int x; int y; };, create one with Point p{3, 4}; and read a member with p.x, or with ptr->x when ptr points to p. Give members default values and create structs with braces, so nothing is left unset. A struct can have everything a class has; its members and base classes are public by default, where a class makes them private.

A struct in C++ is a type you define that groups several values, its members, under one name: struct Point { int x; int y; };. You create one with Point p{3, 4}; and read a member with a dot, p.x. A struct can do everything a class can; its members are public unless you say otherwise.
A whole program that makes a Point, prints it and changes one member:
#include <iostream>
struct Point {
int x;
int y;
};
int main() {
Point p{3, 4};
std::cout << p.x << ", " << p.y << '\n'; // prints 3, 4
p.x = 10;
std::cout << p.x << ", " << p.y << '\n'; // prints 10, 4
}— end example]
It printed:
3, 4
10, 4— end example]
The samples are C++17, built with MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2 and Clang 23.1 (libc++), and all four printed the same. Two features below need C++20, and each says so; Since When lists the first compiler releases for each standard’s features.
How do you initialize a struct in C++?
Put the values in braces, in the order the members are declared. A member you leave out takes the default value written in the struct, and a member with no default is set as if from empty braces, which makes an int 0 (aggregate initialization on cppreference). This Player gives score a default:
struct Player {
std::string name;
int score = 0; // a default value
};
// ...
Player ada{"Ada", 90}; // in the order the members are declared
Player guest; // name is empty, score takes its default
Point origin{}; // empty braces: x and y are 0
std::cout << ada.name << ' ' << ada.score << '\n'; // Ada 90
std::cout << '[' << guest.name << "] " << guest.score
<< '\n'; // [] 0
std::cout << origin.x << ", " << origin.y << '\n'; // 0, 0— end example]
It printed:
Ada 90
[] 0
0, 0— end example]
guest had no braces and still came out set: a std::string starts empty, and score took its default. An int with no default gets no such help.
Since C++20 you can also name each member as you set it, with a designated initializer; the names must come in the order the members are declared (the first compilers with designated initializers):
Point p{.x = 3, .y = 4}; // C++20: designated initializers
std::cout << p.x << ", " << p.y << '\n'; // prints 3, 4— end example]
Built as C++20, all four printed 3, 4. Built as C++17, MSVC refused the line with error C7555, which asks for /std:c++20, while GCC and Clang accepted it as an extension, without a warning at -Wall -Wextra.
How do you access the members of a struct?
Use a dot on the struct itself, ada.score, and an arrow through a pointer to it, p->score.

Player ada{"Ada", 90};
ada.score = 95; // a dot on the struct itself
Player* p = &ada; // a pointer to ada
p->score += 5; // an arrow through the pointer
std::cout << ada.name << ' ' << ada.score << '\n'; // Ada 100
std::cout << p->name << ' ' << (*p).score << '\n'; // Ada 100— end example]
Both lines printed Ada 100, because p holds the address of ada itself, not a copy. (*p).score, which follows the pointer and then uses a dot, reached the same member as p->score: the arrow is the short way to write it.
How do you pass a struct to a function, or return one?
Take it as const Player&, a reference to the caller’s struct that the function can read but not change, so nothing is copied. Return a struct to hand back several values at once:
void print(const Player& player) { // reads it, copies nothing
std::cout << player.name << ": " << player.score << '\n';
}
struct MinMax {
int min;
int max;
};
MinMax min_max(const std::vector<int>& scores) {
MinMax result{scores[0], scores[0]};
for (int s : scores) {
if (s < result.min) result.min = s;
if (s > result.max) result.max = s;
}
return result; // two values handed back as one
}
// ...
print(Player{"Ada", 90}); // prints Ada: 90
std::vector<int> scores{72, 90, 85};
auto [low, high] = min_max(scores); // C++17: structured binding
std::cout << low << ' ' << high << '\n'; // prints 72 90— end example]
It printed Ada: 90, then 72 90. auto [low, high] is a structured binding, new in C++17: it takes one name per member of the returned struct, so low got min and high got max.
Can a struct have functions and constructors?
Yes: a struct can have member functions, constructors and everything else a class can have. This Player has a constructor and two member functions:
struct Player {
std::string name;
int score;
Player(std::string n, int s) : name(std::move(n)), score(s) {}
void add(int points) { score += points; }
void print() const {
std::cout << name << ": " << score << '\n';
}
};
// ...
Player ada("Ada", 90); // calls the constructor
ada.add(10);
ada.print(); // prints Ada: 100— end example]
It printed Ada: 100. A struct with a constructor is created with that constructor’s arguments, as ada is here. It is no longer an aggregate, the plain kind of struct that braces fill member by member. The C++ constructor answer covers default, copy and move constructors.
Struct vs class in C++: what is the difference?
Only the defaults. A struct’s members are public unless you write private:, and a class’s are private unless you write public: (class declaration on cppreference). The same holds for base classes, the types a struct or class inherits from: public by default in a struct, private in a class (derived classes on cppreference).
The same two members in a class cannot be reached from main:
class Point {
int x; // private: a class's default
int y;
};
int main() {
Point p{};
p.x = 3; // error: x is private
}— end example]
Clang stopped at the assignment, and GCC and MSVC refused it too:
error: 'x' is a private member of 'Point'— end example]
| Question | struct |
class |
|---|---|---|
| Members and base classes, by default | public | private |
| Use it when | the members can each hold any value | the type has a rule its members must keep |
The second row is the convention of the C++ Core Guidelines (C.2); they also ask for class whenever any member is not public (C.8).
How do you keep structs in a vector?
Make a std::vector<Player>, add each player with push_back({"Ada", 90}), and loop over them with a range-for that takes each one as const Player&:
std::vector<Player> players;
players.push_back({"Ada", 90});
players.push_back({"Grace", 85});
players.push_back({"Linus"}); // score takes its default, 0
for (const Player& p : players) {
std::cout << p.name << ": " << p.score << '\n';
}— end example]
It printed Ada: 90, Grace: 85 and Linus: 0. How a vector stores its elements and grows is in the std::vector answer.
A struct checklist
- Give each member a default value, as
int score = 0;does. - Create structs with braces:
Player ada{"Ada", 90};, orPoint p{};for all zeros. - Pass a struct to a function as
const Player&; return one to hand back several values. - Write
structfor plain data anyone may read and change,classwhen the type protects its data. - Expect
==on a struct to compile only once there is anoperator==for the type (the FAQ shows the C++20 line).
The Language section has the other answers on the core language.
Questions
What is the difference between a struct and a class in C++?
Only the default access. A struct’s members and base classes are public unless you write private: or protected:, and a class’s are private unless you write public:. Apart from that the two keywords declare the same kind of type, so a struct can have constructors, member functions and private members too.
Can a struct have a constructor in C++?
Yes. A struct can have constructors and member functions, like a class. Once it has a constructor, you create it with that constructor’s arguments, as in Player ada(“Ada”, 90);, and braces no longer fill it member by member.
Can you compare two structs with == in C++?
Not by default: C++ does not write one unless asked, and a == b compiles only once there is an operator== for the type. The line bool operator==(const Point&) const = default; inside the struct has the compiler compare the members in the order they are declared, and != works from it too. That line needs C++20 (-std=c++20, or /std:c++20 on MSVC); before C++20, write the operator yourself, comparing member by member.
How do you initialize a struct to zero?
Write empty braces: for struct Point { int x; int y; };, Point origin{}; sets x and y to 0. A member that has a default value written in the struct takes that value instead. Without the braces, a local Point origin; leaves x and y, its int members, unset.
What is the size of a struct in C++?
At least the sum of its members’ sizes, and often more, because the compiler may add padding, unused bytes that let each member start where its type needs. For struct Mixed { char c; int i; };, sizeof printed 8 on MSVC, GCC and Clang: 5 bytes of members and 3 of padding. Ask sizeof rather than adding the members up.
Can a struct inherit from another struct?
Yes. A struct can inherit from a struct or a class exactly as a class can. The one difference is the default: with no access word before the base’s name, inheritance is public when the type being declared is a struct and private when it is a class, whatever keyword the base was declared with.
Sources
- Aggregate initializationcppreference.com
- Default initializationcppreference.com
- Class declarationcppreference.com
- Derived classescppreference.com
- Structured binding declarationcppreference.com
- Default comparisonscppreference.com
- C++ Core Guidelines, C.2: Use class if the class has an invariant; use struct if the data members can vary independentlyStandard C++ Foundation