Вы ищете std::pointer_traits<PointerType>::element_type
, который живет в <memory>
.
#include <memory>
#include <boost/optional.hpp>
template <class Ptr>
struct MyPointer
{
};
template <class Ptr>
struct YourPointer
{
typedef signed char element_type;
};
int main()
{
static_assert
(
std::is_same
<
std::pointer_traits<std::unique_ptr<double>>::element_type,
double
>::value,
""
);
static_assert
(
std::is_same
<
std::pointer_traits<std::unique_ptr<short[]>>::element_type,
short
>::value,
""
);
static_assert
(
std::is_same
<
std::pointer_traits<std::shared_ptr<const char>>::element_type,
const char
>::value,
""
);
static_assert
(
std::is_same
<
std::pointer_traits<boost::optional<int*>>::element_type,
int*
>::value,
""
);
static_assert
(
std::is_same
<
std::pointer_traits<MyPointer<long long>>::element_type,
long long
>::value,
""
);
static_assert
(
std::is_same
<
std::pointer_traits<YourPointer<long long>>::element_type,
signed char
>::value,
""
);
}
20.6.3.1 Типы элементов черты указателя [pointer.traits.types]
typedef
см. Ниже element_type
;
Тип: Ptr::element_type
, если такой тип существует; в противном случае T
, если Ptr
- создание экземпляра шаблона класса в форме SomePointer<T,
Args>
, где Args
- ноль или более аргументов типа; в противном случае
специализация плохо сформирована.
Да, и есть специализация для типов указателей:
template <class T>
struct pointer_traits<T*>
{
typedef T* pointer;
typedef T element_type;
typedef ptrdiff_t difference_type;
template <class U> using rebind = U*;
static pointer pointer_to(see below r) noexcept;
};