Espacios de nombres
Variantes

atributo de C++: no_unique_address (desde C++20)

De cppreference.com
 
 
 
 
 

Indica que este dato miembro no necesita tener una dirección distinta de todos los otros datos miembro de su clase.

Sintaxis

[[no_unique_address]]

Explicación

Se aplica al nombre que está declarándose en la declaración de un dato miembro no estático y que no es un campo de bits.

Indica que este dato miembro no necesita tener una dirección distinta de todos los otros datos miembro no estáticos. Esto quiere decir que si el miembro tiene un tipo vacío (p. ej., un asignador de memoria que no mantiene estado), el compilador puede optimizarlo para que no ocupe espacio, tal como si fuera una base vacía. Si el miembro no está vacío, cualquier relleno al final también puede ser reutilizado para almacenar otros datos miembro.


Ejemplo

#include <iostream>

struct Vacia {}; // clase vacía

struct X {
    int i;
    Vacia e;
};

struct Y {
    int i;
    [[no_unique_address]] Vacia e;
};

struct Z {
    char c;
    [[no_unique_address]] Vacia e1, e2;
};

struct W {
    char c[2];
    [[no_unique_address]] Vacia e1, e2;
};

int main()
{
    // el tamaño de cualquier objeto de un tipo clase vacío es al menos 1
    static_assert(sizeof(Vacia) >= 1);

    // se necesita al menos un byte más para darle a e una dirección única
    static_assert(sizeof(X) >= sizeof(int) + 1);

    // miembro vacío optimizado
    std::cout << "sizeof(Y) == sizeof(int) es" << std::boolalpha 
              << (sizeof(Y) == sizeof(int)) << '\n';

    // e1 y e2 no pueden compartir la misma dirección porque tienen el
    // mismo tipo, aún cuando están marcados con [[no_unique_address]]. 
    // Sin embargo, cualquiera de los dos puede compartir su dirección con c.
    static_assert(sizeof(Z) >= 2);

    // e1 y e2 no pueden tener la misma dirección, pero uno de ellos puede compartir con
    // c[0] y el otro con c[1]
    std::cout << "sizeof(W) == 2 es" << (sizeof(W) == 2) << '\n';
}

Posible salida:

sizeof(Y) == sizeof(int) es true
sizeof(W) == 2 es true