Open In App

Designated Initializers in C++ 20

Last Updated : 14 May, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

With C++20, we get a convenient way of initializing data members. The new feature is called Designated Initializers and it might be familiar to C programmers. In other words, Designated Initializers are a new feature that has been introduced in C++20. It allows developers or programmers to initiate data members of a struct or an array in any order they want, providing a more readable and flexible way of initializing data members. 

In C++20, a Collection type is defined as an array type or a class type that meets certain criteria. A Collection type shouldn’t have any private or protected direct non-static data members, user-declared or inherited constructors, virtual, private, or protected base classed or virtual member functions. This definition helps to identify and distinguish Collection types from other types in C++.

Syntax:

struct_type obj_name = { 
    .member1 = value1, .member2 = value2, member3 = value3, ...... .memberN = valueN 
};

Where,

  • struct_type: The name of the struct type.
  • obj_name: The name of the object being initialized.
  • member1 to memberN: The names of the data members being initialized.
  • value1 to valueN: The values being assigned to the corresponding data members.
  • We use the dot operator (.) followed by the member name to specify the member we want to initialize.

Why to use Designated Initializers?

  • Designated Initializers increase readability.
  • It is a convenient way of initializing data members.
  • Designated Initializers help to identify and distinguish Collection types from other types in C++.

Example:

C++




// C++ Program to initialize Structure Date with dt
// Designated Initializer
#include <iostream>
using namespace std;
// Create Structure
struct Date {
    int year;
    int month;
    int day;
};
  
int main()
{
  
    Date dt{ .year = 2023, .month = 4, .day = 24 };
  
    cout << "Year : " << dt.year << "\n";
    cout << "Month : " << dt.month << "\n";
    cout << "Day : " << dt.day;
  
    return 0;
}


Output

Year : 2023
Month : 4
Day : 24

Advantages of Designated Initializers

Designated Initializers in C++20 offer several benefits:

  • Readability and Maintainability: By using designated initializers, it’s easy to understand which member is being initialized with what value, even if the struct has many members.
  • Partial or Subset Initialization: It allows us to initialize only a subset of members in the struct. This can be useful when we don’t want to initialize all members of the strict or when we only need to initialize a few members.
  • Flexible Initialization: It allows us to initialize the members of a struct or array in any order we want. This can be useful when we want to initialize the members in a specific order or when we want to group related members together.
  • Nested Structs and Arrays: Designated Initializers can also be used to initialize nested structs or Arrays, making the initialization of complex data structures more straightforward and easier to read. It can also reduce the amount of boilerplate code required for initialization, as we can directly specify the values for each member instead of creating temporary variables or using multiple assignment statements.

Example 1:

C++




// C++ Program to initialize a struct from a list of values
#include <iostream>
using namespace std;
  
struct Date {
    int month;
    int year;
};
  
int main()
{
    // dt.month = 4, dt.year = 2023
    Date dt{ 4, 2023 };
  
    cout << "Month : " << dt.month << "\n";
    cout << "Year : " << dt.year << "\n";
  
    return 0;
}


Output

Month : 4
Year : 2023

Now, imagine if we were to update the struct definition by adding a new member, which is not the last member.

Example 2:

C++




#include <iostream>
using namespace std;
  
struct Date {
    int day;
    int month;
    int year;
};
  
int main()
{
    // dt.day = 4, dt.month = 2023, dt.year = 0
    Date dt{ 4, 2023 };
  
    cout << "Month : " << dt.month << "\n";
    cout << "Year : " << dt.year << "\n";
    cout << "Day : " << dt.day;
    return 0;
}


Output

Month : 2023
Year : 0
Day : 4

However, with Designated Initializers, we can simply add the new member and update its value without affecting initialization code. This can save time and effort while also reducing the chances of introducing bugs due to human error.

Initializing with Designated Initializers

Example:

C++




#include <iostream>
using namespace std;
  
struct Date {
    int day;
    int month;
    int year;
};
  
int main()
{
    Date dt{ .day = 24, .month = 4, .year = 2023 }; // dt.day = 24, dt.month = 4, dt.year = 2023
      
      cout << "Month : " << dt.month << "\n";
    cout << "Year : " << dt.year << "\n";
    cout << "Day : " << dt.day;
      return 0;
}


Output

Month : 4
Year : 2023
Day : 24

Example:

C++




// C++ program to initialize a subset of members of a struct
// using designated initializers
#include <iostream>
using namespace std;
  
struct Rectangle {
    int length;
    int width;
    int height;
};
  
int main()
{
    Rectangle rect = { .length = 10, .width = 5 };
    cout << " Length : " << rect.length << "\n";
    cout << " Width : " << rect.width << "\n";
    cout << " Height : " << rect.height;
    return 0;
}


Output

 Length : 10
 Width : 5
 Height : 0


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads