Пространства имён
Варианты
Действия

std::to_address

Материал из cppreference.com
 
 
Библиотека утилит
Языковая поддержка
Поддержка типов (базовые типы, RTTI)
Макросы тестирования функциональности библиотеки (C++20)    
Управление динамической памятью
Программные утилиты
Поддержка сопрограмм (C++20)
Вариативные функции
Трёхстороннее сравнение (C++20)
(C++20)
(C++20)(C++20)(C++20)(C++20)(C++20)(C++20)
Общие утилиты
Дата и время
Функциональные объекты
Библиотека форматирования (C++20)
(C++11)
Операторы отношения (устарело в C++20)
Целочисленные функции сравнения
(C++20)(C++20)(C++20)    
(C++20)
Операции обмена и типа
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
Общие лексические типы
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
Элементарные преобразования строк
(C++17)
(C++17)
 
Динамическое управление памятью
no section name
Ограниченные алгоритмы неинициализированной памяти
no section name
Поддержка сбора мусора
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)



no section name
 
<tbody> </tbody>
Определено в заголовочном файле <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.

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) [править]