std::to_address — cppreference.com
Материал из cppreference.com
<tbody> </tbody>
| Определено в заголовочном файле |
||
|
|
(1) | (начиная с C++20) |
|
|
(2) | (начиная с C++20) |
Получает адрес, представленный p, не формируя ссылку на объект, на который указывает p.
1) Перегрузка причудливого указателя: если выражение std::pointer_traits<Ptr>::to_address(p) корректно, возвращает результат этого выражения. Иначе возвращает std::to_address(p.operator->()).
2) Перегрузка сырого указателя: если T является функциональным типом, программа некорректна. Иначе возвращает p без изменений.
Параметры
| p | — | причудливый или сырой указатель |
Возвращаемое значение
Сырой указатель, представляющий тот же адрес, что и p.
Возможная реализация
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->()); }
Примечание
std::to_address можно использовать, даже если p не ссылается на хранилище, в котором создан объект, и в этом случае {{c|std::addressof(*p)} } нельзя использовать, потому что нет допустимого объекта для параметра std::addressof для привязки.
Перегрузка std::to_address для причудливого указателя проверяет специализацию std::pointer_traits<Ptr>. Если реализация этой специализации сама по себе некорректна (обычно из-за того, что element_type не может быть определён), это приводит к серьезной ошибке вне непосредственного контекста и делает программу некорректной.
std::to_address может дополнительно использоваться в итераторах, которые соответствуют contiguous_iterator.
| Макрос Тестирования функциональности | Значение | Стандарт | Функциональность |
|---|---|---|---|
__cpp_lib_to_address |
201711L |
(C++20) | Утилита для преобразования указателя в сырой указатель (std::to_address)
|
Пример
#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); }
Смотрите также
| предоставляет информацию о типах, подобных указателям (шаблон класса) [править] | |
[static] (C++20)(необязательно) |
получает сырой указатель из причудливого указателя (обратная pointer_to) (public static функция-элемент std::pointer_traits) [править]
|