Plantilla estándar de C++ (STL): compatibilidad con tipos()

Los objetos, las referencias, las funciones (incluidas las especializaciones de plantillas de funciones) y las expresiones tienen propiedades llamadas tipos , que restringen las operaciones permitidas en estas entidades y proporcionan significado semántico a secuencias de bits que de otro modo serían ordinarias.

Macros y tipos básicos adicionales

Constante de puntero nulo definida por la implementación

NULL

definido en el archivo de encabezado<clocale>

definido en el archivo de encabezado<cstddef>

definido en el archivo de encabezado<cstdio>

definido en el archivo de encabezado<cstdlib>

definido en el archivo de encabezado<cstring>

definido en el archivo de encabezado<ctime>

definido en el archivo de encabezado<cwchar>

#define NULL /*definido por implementación*/

La macro NULLes una constante de puntero nulo definida por la implementación que se puede

expresión constante literal rvalue de tipo entero que se evalúa como cero

(anterior a C++11)

un literal entero con valor cero o un valor pr de tipo std::nullptr_t

(desde C++11)

Una constante de puntero nulo es implícitamente convertible a cualquier tipo de puntero; el resultado de esta conversión es un valor de puntero nulo de ese tipo. Si una constante de puntero nulo tiene un tipo entero, también se puede convertir en un valor pr de tipo std::nullptr_t.

posible implementación

#define NULL 0
// C++11 起
#define NULL nullptr

Aviso

En C, las macros NULLpueden tener tipos void*, pero esto no está permitido en C++.

Ejemplo de llamada

#include <cstddef>
#include <type_traits>
#include <iostream>

class S;

int main()
{
    int* p = NULL;
    int* p2 = static_cast<std::nullptr_t>(NULL);
    void(*f)(int) = NULL;
    int S::*mp = NULL;
    void(S::*mfp)(int) = NULL;

    if (std::is_same<decltype(NULL), std::nullptr_t>::value)
    {
        std::cout << "NULL implemented with type std::nullptr_t" << std::endl;
    }
    else
    {
        std::cout << "NULL implemented using an integral type" << std::endl;
    }
    return 0;
}

 producción

Un tipo trivial con requisitos de alineación de memoria no menores que los de cualquier tipo subyacente.

std::max_align_t

definido en el archivo de encabezado<cstddef>

typedef /*definido por implementación*/ max_align_t;

(desde C++11)

 Aviso

Los punteros devueltos por funciones de asignación como std::malloc son adecuados para alinear cualquier objeto, lo que significa que la alineación es al menos tan estricta como std::max_align_t .

std::max_align_t suele ser sinónimo del tipo escalar más grande, doble largo en la mayoría de las plataformas, y su requisito de alineación es 8 o 16.

Ejemplo de llamada

#include <iostream>
#include <cstddef>

int main()
{
    std::cout << "alignof(std::max_align_t): "
              << alignof(std::max_align_t) << std::endl;
    return 0;
}

producción

El desplazamiento de bytes desde el inicio del tipo de diseño estándar hasta su miembro especificado

offsetof

definido en el archivo de encabezado<cstddef>

#define offsetof(tipo, miembro) /*definido por implementación*/

La macro offsetof se expande a una expresión constante entera de tipo std::size_t. Su valor es el número de bytes desplazados desde el principio del objeto de tipo especificado hasta su miembro especificado, incluidos los bytes de relleno si los hay.

Si no es un tipo de diseño estándar, el comportamiento no está definido (antes de C++ 17) . El uso de macros se typeadmite condicionalmente (desde C++ 17).offsetof

Si memberes un miembro estático o una función miembro, el comportamiento no está definido.

El desplazamiento del primer miembro de un tipo de diseño estándar es siempre cero (la optimización de la clase base vacía es obligatoria).

Una expresión offsetof(type, member)nunca depende de un tipo y depende de un valor si y sólo si el tipo es dependiente.

anormal

offsetofNo se lanza ninguna excepción; la expresión noexcept(offsetof(type, member)) siempre se evalúa como verdadera.

Aviso

offsetofNo se puede implementar en C++ estándar y requiere compatibilidad con el compilador: GCC , LLVM

 Ejemplo de llamada

#include <iostream>
#include <cstddef>

struct S
{
    char c;
    double d;
};

int main()
{
    std::cout << "the first element is at offset "
              << offsetof(S, c) << std::endl
              << "the double is at offset "
              << offsetof(S, d) << std::endl;
    return 0;
}

producción

Supongo que te gusta

Origin blog.csdn.net/qq_40788199/article/details/133430404
Recomendado
Clasificación