List initialization is a powerful feature in C++, but it has limitations, particularly when dealing with classes that have private or protected members.
When you have private or protected members, you cannot directly use list initialization to initialize those members outside the class.
This is because list initialization, like aggregate initialization, relies on public access to the members being initialized. Consider the following example:
#include <iostream>
class Vec3 {
int x, y, z;
public:
Vec3(int a, int b, int c)
: x{a}, y{b}, z{c} {}
void Log() {
std::cout << "x=" << x
<< ", y=" << y
<< ", z=" << z;
}
};
int main() {
Vec3 Vector{1, 2, 3};
Vector.Log();
}
x=1, y=2, z=3
In this example, Vec3
has private members x
, y
, and z
. The class provides a public constructor that initializes these members, allowing us to use list initialization in main()
.
If the class did not have this constructor, we would not be able to use list initialization directly:
#include <iostream>
class Vec3 {
int x, y, z;
public:
// Vec3(int a, int b, int c)
// : x{a}, y{b}, z{c} {}
void Log() {
std::cout << "x=" << x
<< ", y=" << y
<< ", z=" << z;
}
};
int main() {
Vec3 Vector{1, 2, 3};
Vector.Log();
}
error: 'initializing': cannot convert from 'initializer list' to 'Vec3'
This code will result in a compilation error because the private members cannot be initialized directly. Instead, you must provide a constructor or use public members if you want to leverage list initialization.
For classes with protected members, the scenario is similar. Only derived classes have access to protected members, and list initialization for protected members can be done within these derived classes using appropriate constructors.
Answers to questions are automatically generated and may not have been reviewed.
A quick guide to creating objects using lists, including std::initializer_list
, aggregate and designated initialization