List Initialization with Private Members

Can we use list initialization for classes with private or protected members?

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.

List, Aggregate, and Designated Initialization

A quick guide to creating objects using lists, including std::initializer_list, aggregate and designated initialization

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Aggregate Initialization for Nested Structures
How does aggregate initialization work for complex types with nested structures?
Using Initializer Lists in Custom Containers
How can we use std::initializer_list to initialize custom container types?
Designated Initializers with Private Members
Can designated initializers be used with types that have private or protected members?
Aggregate Initialization with Inheritance
How does aggregate initialization interact with inheritance and derived classes?
Heterogeneous Initializer Lists
Can std::initializer_list be used with heterogeneous data types in any way?
List Initialization with constexpr and constinit
How does list initialization interact with constexpr and constinit specifiers in C++20?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant