To be more specific, suppose I am writing template<class Pointer> class Foo
and I want to declare a typedef
inside the class for the type that *p
would have if p
were of type Pointer
.
In C++03, as far as I am aware, the only way to do this is with something like
typename std::iterator_traits<Pointer>::reference
The disadvantage of this method is that it won't work if Pointer
is some custom iterator type and the author forgot to extend std::iterator
or otherwise define a std::iterator_traits
specialization.
In C++11, my colleague suggested
decltype(*Pointer())
But this won't work if Pointer
is not default-constructible, so he amended this to
decltype(**(Pointer*)0)
I tried this, and it worked, but then I thought that it looked a bit iffy because it involves the dereference of a null pointer, and thus might not be standards-compliant.
Can we do better?
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.
The fundamental rules of pointer operators are: The * operator turns a value of type pointer to T into a variable of type T . The & operator turns a variable of type T into a value of type pointer to T .
A pointer hold an address in memory. An iterator may hold a pointer, but it may be something much more complex. For example, an iterator can iterate over data that's on file system, spread across many machines, or generated locally in a programmatic fashion.
An iterator is an object (like a pointer) that points to an element inside the container. We can use iterators to move through the contents of the container. They can be visualized as something similar to a pointer pointing to some location and we can access the content at that particular location using them.
You're right to be cautious about dereferencing a null pointer, but the fact is that it's ok here! decltype
does not evaluate its operand, so dereferencing a null pointer inside is perfectly valid.
The proper solution, however, is std::declval
, introduced inside <utility>
in C++11:
decltype(*std::declval<Pointer>())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With