std::pointer_traits — cppreference.com
Материал из cppreference.com
<tbody> </tbody>
| Определено в заголовочном файле |
||
|
|
(1) | (начиная с C++11) |
|
|
(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...>
|
Функции-элементы
| получает разыменованный указатель на свой аргумент (public static функция-элемент) [править] |
2) Для типов указателей предусмотрена специализация T*, которая объявляет следующие элементы:
Типы элементы
| Тип | Определение |
pointer
|
T*
|
element_type
|
T
|
difference_type
|
std::ptrdiff_t |
Элементы шаблоны псевдонимы
| Шаблон | Определение |
template< class U > using rebind
|
U*
|
Функции-элементы
| получает разыменованный указатель на свой аргумент (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);
|
Специализация для определяемых пользователем причудливых типов указателей может предоставлять дополнительную статическую функцию-элемент |
(начиная с 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'; }
Вывод:
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| LWG 3545 | C++11 | основной шаблон вызывал серьёзную ошибку, когда element_typeбыл недействительным |
сделано SFINAE-дружественным |