Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a pointer type's pointed type?

Tags:

c++

typetraits

I have a pointer type Ptr. It might be T*, unique_ptr, shared_ptr, or others. How to get its pointed type at compilation time? I try the following but failed

template<class Ptr>
void f()
{
    typedef decltype(*Ptr()) T; // give unexpected results
}

The following deleted answer works very well.

typedef typename std::remove_reference<decltype(*std::declval<Ptr>())>::type T;
like image 689
user1899020 Avatar asked May 16 '14 20:05

user1899020


People also ask

Can pointer point to another type?

The pointers can point to any type if it is a void pointer. but the void pointer cannot be dereferenced. only if the complier knows the data type of the pointer variable, it can dereference the pointer and perform the operations.

Can a pointer refer to any type?

Every pointer is of some specific type. There's a special generic pointer type void* that can point to any object type, but you have to convert a void* to some specific pointer type before you can dereference it.

What do pointers store?

A pointer is a variable that stores a memory address. Pointers are used to store the addresses of other variables or memory items. Pointers are very useful for another type of parameter passing, usually referred to as Pass By Address. Pointers are essential for dynamic memory allocation.


2 Answers

This is one way to do it.

Create a helper class, with appropriate specializations to deduce the pointer type.

template <typename T> Pointer;

template <typename T> Pointer<T*>
{
   typedef T Type;
};

template <typename T> Pointer<shared_ptr<T>>
{
   typedef T Type;
};

template <typename T> Pointer<unique_ptr<T>>
{
   typedef T Type;
};

template<class Ptr>
void f()
{
    typedef typename Pointer<Ptr>::Type PointerType;
}
like image 167
R Sahu Avatar answered Oct 21 '22 14:10

R Sahu


I was in the middle of writing up this answer when I saw someone else had already posted it, so I gave up. But then that other answer disappeared, so here it is. If the original reappears, I'll delete this.

If Ptr is (for example) int*, then decltype(*Ptr()) evaluates to int& rather than int, which is probably the cause of your error (whatever it is). Try:

std::remove_reference<decltype(*Ptr())>::type

Or, if it's possible Ptr might not have a default constructor:

std::remove_reference<decltype(*std::declval<Ptr>())>::type

like image 32
dlf Avatar answered Oct 21 '22 14:10

dlf