24

What would be the most generic syntax for the following function :

template<IteratorType> void myFunction(const IteratorType& myIterator)
{
    _ptr = &myIterator[0];
}

It take an iterator myIterator (it can be a raw pointer) and the goal is to assign the address of the object pointed by myIterator to a raw pointer _ptr. Currently I use &myIterator[0] but I realized that only random access iterators have the operator [].

So is there a syntax that will work with all type of standard iterators and pointers ?

Matt
  • 22,721
  • 17
  • 71
  • 112
Vincent
  • 57,703
  • 61
  • 205
  • 388
  • 2
    This might be a bit trickier than what you are showing in the case there the stored element overrides `operator&`... – David Rodríguez - dribeas Aug 29 '12 at 13:55
  • @DavidRodríguez-dribeas: [Indeed](http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Address_Of) (although these days we've got `std::addressof` rather than that gibberish) – Mike Seymour Aug 29 '12 at 14:26

4 Answers4

39

You can dereference pointer and then take address of object.

template<IteratorType> void myFunction(const IteratorType& myIterator)
{
    _ptr = &(*myIterator);
}
ForEveR
  • 55,233
  • 2
  • 119
  • 133
29

According to standard * operator return a reference so in my opinion the best way is &*myIterator, but since the class may overloaded the & operator the best way is std::addressof(*myIterator) that work for all classes

BigBoss
  • 6,904
  • 2
  • 23
  • 38
  • 9
    +1 for std::addressof. If there is no C++11, one can use boost::addressof. – ForEveR Aug 29 '12 at 13:49
  • Only forward iterators promise to return references, input and output iterators can return proxy objects, which `&` is inappropriate for. – Caleth Jun 24 '21 at 10:27
  • You must guarantee that whatever iterator you apply that to, must be valid. I.e. a non-end iterator. Otherwise... you know... demons. – Adrian Oct 30 '21 at 03:18
8

All iterators are required to have operator * (24.2.2:2), so you can write

_ptr = &*myIterator;

However, this is not valid for output iterators, where *r is only valid on the left hand side of an assignment operation (24.2.4:2).

Also note that it is not necessarily true that *r will provide a value that & can sensibly be applied to; the specialization std::vector<bool> (23.3.7) has a reference type that is not bool &, for example. In your case the assignment _ptr = &*myIterator would catch this, assuming that _ptr is an appropriate pointer type, and you would get a compile failure.

ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • You must guarantee that whatever iterator you apply that to, must be valid. I.e. a non-end iterator. Otherwise... you know... demons. – Adrian Oct 30 '21 at 03:19
1

I hope you guys are all alive right now. If your iterator is an iterator for std::vector, there is a nicer way to get the address that the iterator is holding. You can use:

auto *ptr = myIterator._Ptr;

I hope I could give a proper answer to your question.

  • This unfortunately is not a portable solution. Any identifier starting with '_' followed by a capital letter is reserved as an implementation detail and isn't guaranteed to be consistent in future versions of even the same implementation. In short, don't use it. – owacoder Aug 27 '21 at 18:09