C++14 and C++20 Updates to NSDMI

In this lesson, we will cover the updates added in C++14 and C++20 for non-static data member initialization.

We'll cover the following

C++14 changes

Originally, in C++11, if you used default member initialization, your class couldn’t be an aggregate type:

struct Point { float x = 1.0f; float y = 2.0f; };

// won't compile in C++11
Point myPt { 10.0f, 11.0f};

The above code won’t work when compiling with the C++11 flag because you cannot aggregate-initialize our Point structure. It’s not an aggregate.

Fortunately, C++14 provides a solution to this problem, and that’s this line:

Point myPt { 10.0f, 11.0f};

Works as expected.

You can see and play with the full code below:

Press + to interact
#include <iostream>
struct Point { float x = 1.0f; float y = 2.0f; };
int main()
{
Point myPt { 10.0f };
std::cout << myPt.x << ", " << myPt.y << '\n';
}

As a reminder, in C++20:




An aggregate is one of the following types:

  • array type
  • class type (typically, struct or union) that has:
    • no private or protected direct non-static data members
    • no user-declared or inherited constructors
    • no virtual, private, or protected base classes
    • no virtual member functions

C++20 changes

Since C++11, the code only considered “regular” fields… but how about bit fields in a class? For example:

class Type {
    int value : 4;
};

Unfortunately, in C++11, it wasn’t possible to default-initialize the value bit field.

However, with a compiler that conforms to C++20, you can write:

Press + to interact
#include <iostream>
struct Type {
int value : 4 = 1;
int second : 4 { 2 };
};
int main() {
Type t;
std::cout << t.value << '\n';
std::cout << t.second << '\n';
}

As you can see above, C++20 offers improved syntax where you can specify the default value after the bit size: var : bit_count { default_value }.

Summary

In summary, C++ added NSDMI in C++11, and it was improved in C++14 (aggregate classes). It also fixed a missing bitfield initialization in C++20.