Namensräume
Varianten
Aktionen

std::to_address

Von cppreference.com
< cpp‎ | memory
 
 
Speicherverwaltungsbibliothek
(nur Exposition*)
Algorithmen für uninitialisierten Speicher
(C++17)
(C++17)
(C++17)
Beschränkte uninitialisierte
Speicher-Algorithmen
C-Bibliothek

Allocatoren
Speicherressourcen
Unterstützung für Garbage Collection
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
Uninitialisierter Speicher
Explizites Lebenszeitmanagement
 
Definiert in Header <memory>
template< class Ptr >
constexpr auto to_address( const Ptr& p ) noexcept;
(1) (seit C++20)
template< class T >
constexpr T* to_address( T* p ) noexcept;
(2) (seit C++20)

Ermittelt die von p dargestellte Adresse, ohne eine Referenz auf das Objekt zu bilden, auf das p zeigt.

1) Fancy Pointer-Überladung: Wenn der Ausdruck std::pointer_traits<Ptr>::to_address(p) wohlgeformt ist, wird das Ergebnis dieses Ausdrucks zurückgegeben. Andernfalls wird std::to_address(p.operator->()) zurückgegeben.
2) Roh-Zeiger-Überladung: Wenn T ein Funktionstyp ist, ist das Programm schlecht geformt. Andernfalls wird p unverändert zurückgegeben.

Inhalt

[edit] Parameter

p - Fancy- oder Roh-Zeiger

[edit] Rückgabewert

Ein Roh-Zeiger, der dieselbe Adresse darstellt wie p.

[edit] Mögliche Implementierung

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

[edit] Hinweise

std::to_address kann auch dann verwendet werden, wenn p keinen Speicher referenziert, auf dem ein Objekt konstruiert wurde. In diesem Fall kann std::addressof(*p) nicht verwendet werden, da es kein gültiges Objekt gibt, an das der Parameter von std::addressof gebunden werden könnte.

Die Fancy-Pointer-Überladung von std::to_address untersucht die Spezialisierung von std::pointer_traits<Ptr>. Wenn die Instanziierung dieser Spezialisierung selbst schlecht geformt ist (typischerweise weil element_type nicht definiert werden kann), führt dies zu einem schwerwiegenden Fehler außerhalb des unmittelbaren Kontexts und macht das Programm schlecht geformt.

std::to_address kann zusätzlich auf Iteratoren angewendet werden, die std::contiguous_iterator erfüllen.

Feature-Test-Makro Wert Std Feature
__cpp_lib_to_address 201711L (C++20) Dienstprogramm zur Konvertierung eines Zeigers in einen Roh-Zeiger (std::to_address)

[edit] Beispiel

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

[edit] Siehe auch

liefert Informationen über zeigerähnliche Typen
(Klassen-Template) [edit]
[static] (C++20)(optional)
Ermittelt einen Roh-Zeiger aus einem Fancy Pointer (Inverse von pointer_to)
(public static member function of std::pointer_traits<Ptr>) [edit]