Namespaces
Variants

std:: to_address

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
Défini dans l'en-tête <memory>
template < class Ptr >
constexpr auto to_address ( const Ptr & p ) noexcept ;
(1) (depuis C++20)
template < class T >
constexpr T * to_address ( T * p ) noexcept ;
(2) (depuis C++20)

Obtenir l'adresse représentée par p sans former une référence à l'objet pointé par p .

1) Surcharge de pointeur sophistiqué : Si l'expression std:: pointer_traits < Ptr > :: to_address ( p ) est bien formée, retourne le résultat de cette expression. Sinon, retourne std :: to_address ( p. operator - > ( ) ) .
2) Surcharge de pointeur brut : Si T est un type de fonction, le programme est mal formé. Sinon, retourne p inchangé.

Table des matières

Paramètres

p - pointeur élégant ou brut

Valeur de retour

Pointeur brut qui représente la même adresse que p le fait.

Implémentation possible

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->());
}

Notes

std::to_address peut être utilisé même lorsque p ne référence pas de stockage dans lequel un objet a été construit, auquel cas std:: addressof ( * p ) ne peut pas être utilisé car il n'y a pas d'objet valide auquel le paramètre de std:: addressof peut se lier.

La surcharge de pointeur sophistiqué de std::to_address inspecte la spécialisation std:: pointer_traits < Ptr > . Si l'instanciation de cette spécialisation est elle-même mal formée (généralement parce que element_type ne peut pas être défini), cela résulte en une erreur grave en dehors du contexte immédiat et rend le programme mal formé.

std::to_address peut également être utilisé sur des itérateurs qui satisfont std::contiguous_iterator .

Macro de test de fonctionnalité Valeur Std Fonctionnalité
__cpp_lib_to_address 201711L (C++20) Utilitaire pour convertir un pointeur en pointeur brut ( std::to_address )

Exemple

#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);
}

Voir aussi

fournit des informations sur les types de pointeurs
(modèle de classe)
[static] (C++20) (optionnel)
obtient un pointeur brut à partir d'un pointeur intelligent (inverse de pointer_to )
(fonction membre statique publique de std::pointer_traits<Ptr> )