std:: to_address
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Определено в заголовке
<memory>
|
||
|
template
<
class
Ptr
>
constexpr auto to_address ( const Ptr & p ) noexcept ; |
(1) | (начиная с C++20) |
|
template
<
class
T
>
constexpr T * to_address ( T * p ) noexcept ; |
(2) | (начиная с C++20) |
Получите адрес, представленный p без создания ссылки на объект, указываемый p .
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
не ссылается на хранилище, в котором сконструирован объект, в таком случае
std::
addressof
(
*
p
)
не может быть использован, поскольку нет валидного объекта для привязки параметра
std::
addressof
.
Перегруженная версия
std::to_address
для умных указателей анализирует
специализацию
std::
pointer_traits
<
Ptr
>
.
Если создание экземпляра этой специализации само по себе некорректно (обычно из-за невозможности определить
element_type
), это приводит к жёсткой ошибке за пределами непосредственного контекста и делает программу некорректной.
std::to_address
также может использоваться с итераторами, удовлетворяющими требованиям
std::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); }
Смотрите также
|
(C++11)
|
предоставляет информацию о указательноподобных типах
(шаблон класса) |
|
[static]
(C++20)
(optional)
|
получает сырой указатель из умного указателя (обратная операция к
pointer_to
)
(публичная статическая функция-член
std::pointer_traits<Ptr>
)
|