В своем коде мне нужно проверить, является ли тип, указанный в шаблоне, указателем — умным он или нет. Согласно boost, не существует надежного и универсального способа сделать это (см. здесь ) — или он есть?
Пока я проверяю следующее:
T
преобразовать в void*
?T
метод get()
?T
тип с именем element_type
?get()
тип element_type*
?Если (A || B && C && D), то я делаю вывод, что мой тип должен быть каким-то указателем.
Вот шаблон:
template
class is_pointer_type
{
typedef struct { char array[1]; } yes;
typedef struct { char array[2]; } no;
template static yes test_g(decltype(&C::get));
template static no test_g(...);
template static yes test_e(typename C::element_type*);
template static no test_e(...);
enum {
has_get = sizeof(test_g(0)) == sizeof(yes),
has_element_type = sizeof(test_e(0)) == sizeof(yes)
};
template
struct get { struct type {}; };
template
struct get
{
typedef decltype(((Q*)nullptr)->get()) type;
};
template
struct ptr { struct type {}; };
template
struct ptr
{
typedef typename Q::element_type* type;
};
public:
enum {
types_ok = std::is_same<
typename get::type,
typename ptr::type
>::value,
value = std::is_convertible::value || types_ok
};
};
Пока все работает нормально. Но есть ли что-то неправильное в этом рассуждении? Стоит ли быть готовым к неприятным сюрпризам? Как насчет const
/ volatile
?
В комментариях вы спрашиваете о моей мотивации, и они правы, я вам должен. Вариант использования — библиотека привязки Lua-C++: при предоставлении экземпляра класса Lua с шаблоном
мне нужно вывести базовый тип U
в любой комбинации T = U const/volatile/*/&
и T = some_pointer
. Мне нужно знать, зарегистрирован ли уже базовый класс U
в связующем.