std::to_address
| 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.
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
| (C++11) |
liefert Informationen über zeigerähnliche Typen (Klassen-Template) |
| [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>) |