std::to_address
De cppreference.com
<tbody>
</tbody>
| 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.Parámetros
| p | - | Puntero sofisticado o sin formato. |
Valor de retorno
Puntero sin formato que representa la misma dirección que p.
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->());
}
}
|
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.
Ejemplo
Ejecuta este código
#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);
}
Véase también
(C++11) |
Proporciona información sobre tipos similares a punteros. (plantilla de clase) |
[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>)
|