Я хочу реализовать is_pointer. Я хочу что-то вроде этого:
template <typename T >
bool is_pointer( T t )
{
// implementation
} // return true or false
int a;
char *c;
SomeClass sc;
someAnotherClass *sac;
is_pointer( a ); // return false
is_pointer( c ); // return true
is_pointer( sc ); // return false
is_pointer( sac ); // return true
Как я могу реализовать его?Спасибо
template <typename T>
struct is_pointer_type
{
enum { value = false };
};
template <typename T>
struct is_pointer_type<T*>
{
enum { value = true };
};
template <typename T>
bool is_pointer(const T&)
{
return is_pointer_type<T>::value;
}
Йоханнес отметил:
Я думаю, здесь фактически отсутствуют специализации для T * const, T * volatile и T * const volatile.
Решение:
template <typename T>
struct remove_const
{
typedef T type;
};
template <typename T>
struct remove_const<const T>
{
typedef T type;
};
template <typename T>
struct remove_volatile
{
typedef T type;
};
template <typename T>
struct remove_volatile<volatile T>
{
typedef T type;
};
template <typename T>
struct remove_cv : remove_const<typename remove_volatile<T>::type> {};
template <typename T>
struct is_unqualified_pointer
{
enum { value = false };
};
template <typename T>
struct is_unqualified_pointer<T*>
{
enum { value = true };
};
template <typename T>
struct is_pointer_type : is_unqualified_pointer<typename remove_cv<T>::type> {};
template <typename T>
bool is_pointer(const T&)
{
return is_pointer_type<T>::value;
}
... но, конечно, это просто новое изобретение колеса std :: type_traits
, более или менее :)
template <typename T>
struct is_pointer
{ static const bool value = false; };
template <typename T>
struct is_pointer<T*>
{ static const bool value = true; };
Вы не можете делать именно то, что хотите. Вам придется использовать это как:
is_pointer<int*>::value
Это невозможно определить во время выполнения.
template <typename T>
bool is_pointer(T const &t) // edited: was "T t"; see the comments
{
return false;
}
template <typename T>
bool is_pointer(T *t)
{
return true;
}
Вы не поверите, но это работает. Причина в том, что будет выбрана наиболее конкретная реализация шаблона, которая принимает тип указателя.
Для этого можно использовать оператор typeid, определенный в typeinfo.h. проверьте эту ссылку: http://en.wikipedia.org/wiki/Typeid
Оператор typeid выдаст объект класса std :: type_info, который имеет функцию name (), возвращающую char *. Как только вы получите тип в строковой форме, вы легко сможете идентифицировать указатель.
Надеюсь, это поможет.
Ромил.