tags:

views:

205

answers:

4

Hi all. I want to implement is_pointer. I want something like this:

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

How can I implement it? Thanks

+10  A: 

From Dr. Dobbs.

template <typename T> 
struct is_pointer 
{ static const bool value = false; };

template <typename T> 
struct is_pointer<T*> 
{ static const bool value = true; };

You can't do exactly what you want to do. You'll have to use this like:

is_pointer<int*>::value

It's not possible to determine this at run time.

Peter Alexander
Well, actually if you can have it at compilation, then you can have it at runtime. The reverse is usually more difficult. Anyway that's the solution I would be aiming for... or just using the Boost Type Traits library.
Matthieu M.
Peter this look good, but please look my example, I want to pass a variable like this: int ival; is_pointer( ival ); instead of is_pointer<int * > or is_pointer(int)
Davit Siradeghyan
+7  A: 
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;
}

You might not believe it, but it works. The reason is that the most specific template implementation will be chosen, which is the one which takes the pointer type.

Thomas
This won't work for noncopyable types.
FredOverflow
True, it's not the best solution. That's why I upvoted Peter Alexander and you after posting this :)
Thomas
Job
FredOverflow
@FredOverflow: Yes of course you're right:)
Job
Elemental
Thomas
+16  A: 
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;
}

Johannes noted:

This is actually missing specializations for T *const, T *volatile and T * const volatile i think.

Solution:

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;
}

...but of course this is just reinventing the std::type_traits wheel, more or less :)

FredOverflow
Is there a reason to use this solution over the one given by Thomas?
Job
@Job It works for noncopyable types :)
FredOverflow
Job
@Job If Davit ever needs to know whether a *type* is a pointer (as opposed to an *expression*), he can use `is_pointer_type`. One stone, two birds :)
FredOverflow
@FredOverflow: Very good point!
Job
This is actually missing specializations for `T *const`, `T *volatile` and `T * const volatile` i think. For this problem, you can call the trait with `is_pointer_type<T const volatile>::value` to work it around, but i suspect it would be nicer to put the burden of work into the trait :)
Johannes Schaub - litb
@Johannes: I have updated my answer.
FredOverflow
@FredOverflow nice :)
Johannes Schaub - litb
A: 

Hi, You can use "typeid" operator defined in typeinfo.h for this. check this link : http://en.wikipedia.org/wiki/Typeid

The typeid operator will give an object of std::type_info class, which has a name() function returning char *. Once you get the type in string form, you can identify the pointer easily.

Hope it helps.

Romil.

Romil
-1, doesn't work. The set of std::type_info::name's for pointers may intersect the set of std::type_info::name's for non-pointers. In particular, all names can legally be `""`.
MSalters
This. The string returned by .name is entirely implementation defined.
DeadMG