Espacios de nombres
Variantes
Acciones

std::to_address

De cppreference.com
< cpp‎ | memory
 
 
Biblioteca de servicios
 
Gestión de memoria dinámica
Punteros inteligentes
(C++11)
(C++11)
(C++11)
(hasta C++17)
(C++11)
(C++23)
Asignadores de memoria
Recursos de memoria
Almacenamiento no inicializado
Algoritmos de memoria no inicializada
Algoritmos restringidos de memoria no inicializada
Apoyo para recolección de basura
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
Misceláneos
to_address
(C++20)
(C++11)
(C++11)
 
Definido en el archivo de encabezado <memory>
template< class Ptr >
constexpr auto to_address(const Ptr& p) noexcept;
(1) (desde C++20)
template< class T >
constexpr T* to_address(T* p) noexcept;
(2) (desde C++20)

Obtiene la dirección representada por p sin formar una referencia al objeto al que apunta p.

1) Sobrecarga de puntero sofisticado Si la expresión std::pointer_traits<Ptr>::to_address(p) está bien formada, devuelve el resultado de esa expresión. De lo contrario, devuelve std::to_address(p.operator->()).
2) Sobrecarga de puntero sin formato: Si T es un tipo función, el programa está mal formado. De lo contrario, devuelve p sin modificar.

Contenido

[editar] Parámetros

p - Puntero sofisticado o sin formato.

[editar] Valor de retorno

Puntero sin formato que representa la misma dirección que p.

[editar] Posible implementación

template<class T>
constexpr T* to_address(T* p) noexcept
{
    static_assert(!std::is_function_v<T>);
    return p;
}
 
template<class T>
constexpr auto to_address(const T& p) noexcept
{
    if constexpr (requires{ std::pointer_traits<T>::to_address(p); }) {
        return std::pointer_traits<T>::to_address(p);
    } else {
        return std::to_address(p.operator->());
    }
}

[editar] Notas

std::to_address puede usarse incluso cuando p no hace referencia a almacenamiento que tiene un objeto construido en él, en cuyo caso std::addressof(*p) no se puede usar porque no hay un objeto válido al que el parámetro de std::addressof se vincule.

La sobrecarga de puntero sofisticado de to_address inspecciona la especialización std::pointer_traits<Ptr>. Si instanciar esa especialización está en sí mismo mal formado (típicamente porque element_type no puede definirse), eso da como resultado un error insalvable fuera del contexto inmediato y hace que el programa esté mal formado.

[editar] Ejemplo

#include <memory>
 
template<class A>
auto allocator_new(A& a)
{
    auto p = a.allocate(1);
    try {
        std::allocator_traits<A>::construct(a, std::to_address(p));
    } catch (...) {
        a.deallocate(p, 1);
        throw;
    }
    return p;
}
 
template<class A>
void allocator_delete(A& a, typename std::allocator_traits<A>::pointer p)
{
    std::allocator_traits<A>::destroy(a, std::to_address(p));
    a.deallocate(p, 1);
}
 
int main()
{
    std::allocator<int> a;
    auto p = allocator_new(a);
    allocator_delete(a, p);
}


[editar] Véase también

Proporciona información sobre tipos similares a punteros.
(plantilla de clase) [editar]
[estático] (C++20)(opcional)
Obtiene un puntero sin formato a partir de un puntero sofisticado (el inverso de pointer_to)
(función miembro estática pública de std::pointer_traits<Ptr>) [editar]