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

std::pointer_traits

Материал из cppreference.com
 
 
Динамическое управление памятью
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
 
std::pointer_traits
Функции-элементы
(C++20)(необязательно)
 
<tbody> </tbody>
Определено в заголовочном файле <memory>
template< class Ptr > struct pointer_traits;
(1) (начиная с C++11)
template< class T > struct pointer_traits<T*>;
(2) (начиная с C++11)

Шаблонный класс pointer_traits предоставляет стандартизированный способ доступа к определённым свойствам типов, подобных указателям (причудливые указатели, например boost::interprocess::offset_ptr). Стандартный шаблон std::allocator_traits использует pointer_traits для определения значений по умолчанию для различных определений типов, требуемых Allocator.

1) Неспециализированный pointer_traits условно объявляет следующие элементы:

Пусть /*тип-элемента*/<Ptr> будет

  • Ptr::element_type, если присутствует;
  • в противном случае T, если Ptr является специализацией шаблона класса Template<T, Args...>, где Args... это ноль или более аргументов типа;
  • иначе не определено.

Если /*тип-элемента*/<Ptr> не определён, основной шаблон не имеет элементов, указанных на этой странице.

Типы элементы

Тип Определение
pointer Ptr
element_type /*тип-элемента*/<Ptr>
difference_type Ptr::difference_type, если присутствует, иначе std::ptrdiff_t

Элементы шаблоны псевдонимы

Шаблон Определение
template <class U> using rebind Ptr::rebind<U>, если существует, иначе Template<U, Args...>, если Ptr является специализацией шаблона Template<T, Args...>

Функции-элементы

[static]
получает разыменованный указатель на свой аргумент
(public static функция-элемент) [править]
2) Для типов указателей предусмотрена специализация T*, которая объявляет следующие элементы:

Типы элементы

Тип Определение
pointer T*
element_type T
difference_type std::ptrdiff_t

Элементы шаблоны псевдонимы

Шаблон Определение
template< class U > using rebind U*

Функции-элементы

[static]
получает разыменованный указатель на свой аргумент
(public static функция-элемент) [править]

Необязательные функции-элементы определяемых программой специализаций

[static] (C++20)(необязательно)
получает сырой указатель из причудливого указателя (обратная pointer_to)
(public static функция-элемент) [править]

Примечание

Псевдоним шаблона rebind позволяет, учитывая тип, подобный указателю, который указывает на T, получить тот же тип, подобный указателю, который указывает на U. Например,

using another_pointer = std::pointer_traits<std::shared_ptr<int>>::rebind<double>;
static_assert(std::is_same<another_pointer, std::shared_ptr<double>>::value);

Специализация для определяемых пользователем причудливых типов указателей может предоставлять дополнительную статическую функцию-элемент to_address для настройки поведения std::to_address.

(начиная с C++20)
Макрос Тестирования функциональности Значение Стандарт Функциональность
__cpp_lib_constexpr_memory 201811L (C++20) constexpr в std::pointer_traits

Пример

#include <memory>
#include <iostream>

template <class Ptr>
struct BlockList
{
    // Предопределённый блок памяти
    struct block;

    // Определяем указатель на блок памяти из указателя вида Ptr s
    // Если Ptr это любой тип T*, block_ptr_t равен block*
    // Если Ptr это smart_ptr<T>, block_ptr_t это smart_ptr<block>
    using block_ptr_t = typename std::pointer_traits<Ptr>::template rebind<block>;

    struct block
    {
        std::size_t size{};
        block_ptr_t next_block{};
    };

    block_ptr_t free_blocks;
};

int main()
{
    [[maybe_unused]]
    BlockList<int*> bl1;
    // Тип bl1.free_blocks это BlockList<int*>:: block*

    BlockList<std::shared_ptr<char>> bl2;
    // Тип bl2.free_blocks это
    // std::shared_ptr< BlockList<std::shared_ptr<char> >::block>
    std::cout << bl2.free_blocks.use_count() << '\n';
}

Вывод:

0

Отчёты о дефектах

Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:

Номер Применён Поведение в стандарте Корректное поведение
LWG 3545 C++11 основной шаблон вызывал серьёзную ошибку, когда element_type
был недействительным
сделано SFINAE-дружественным

Смотрите также

предоставляет информацию о типах аллокаторов
(шаблон класса) [править]
(C++11)
получает фактический адрес объекта, даже если оператор & перегружен
(шаблон функции) [править]