std::pointer_traits
| Определено в заголовочном файле <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.
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 функция-элемент) |
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);
|
Специализация для определяемых пользователем причудливых типов указателей может предоставлять дополнительную статическую функцию-элемент |
(начиная с 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) |
предоставляет информацию о типах аллокаторов (шаблон класса) |
(C++11) |
получает фактический адрес объекта, даже если оператор & перегружен (шаблон функции) |