Designated Initializers (C++20)

Named struct initialization from C

The Feature

C++20 brings C-style designated initializers, allowing you to initialize struct members by name.

struct Config {
    const char* host;
    int port;
    bool use_ssl;
    int timeout_ms;
};

// C++20: Designated initialization
Config cfg = {
    .host = "localhost",
    .port = 8080,
    .use_ssl = false,
    .timeout_ms = 5000
};

// Order doesn't matter!
Config cfg2 = {
    .port = 443,
    .host = "example.com",
    .timeout_ms = 10000,
    .use_ssl = true
};

// Can omit fields (initialized to zero/false/nullptr)
Config cfg3 = {
    .host = "api.server.com",
    .port = 80
};  // use_ssl = false, timeout_ms = 0

Restrictions

// Must use same order as declaration (C++20 restriction)
struct Point { int x; int y; };

Point p = {
    .x = 1,
    .y = 2   // OK: same order
};

// This is an error in C++20 (C allows any order):
// Point bad = {
//     .y = 2,
//     .x = 1  // Error: out of order!
// };

// Cannot mix designated and non-designated
// Point bad2 = { 1, .y = 2 };  // Error!

// Cannot designate array elements directly
struct Data {
    int values[3];
};

// Data d = { .values[0] = 1 };  // Error in C++20

Use Cases

// Configuration structures
struct WindowConfig {
    int width = 800;
    int height = 600;
    const char* title = "Application";
    bool fullscreen = false;
    bool vsync = true;
};

// Self-documenting initialization
WindowConfig game_window = {
    .width = 1920,
    .height = 1080,
    .title = "My Game",
    .fullscreen = true,
    .vsync = false
};

// Function arguments via struct
void connect(const Config& cfg);

// Clear call sites
connect({
    .host = "db.example.com",
    .port = 5432,
    .use_ssl = true,
    .timeout_ms = 30000
});

Benefits

  • Self-documenting code - field names visible at initialization
  • Can skip fields - use defaults for unspecified members
  • Compile-time checking - wrong field names are errors
  • Better than positional initialization for many fields