Address of the pointed element whatever the iterator type/pointer is passed
Asked Answered
A

4

25

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 ?

Amando answered 29/8, 2012 at 13:47 Comment(2)
This might be a bit trickier than what you are showing in the case there the stored element overrides operator&...Favianus
@DavidRodríguez-dribeas: Indeed (although these days we've got std::addressof rather than that gibberish)Become
F
40

You can dereference pointer and then take address of object.

template<IteratorType> void myFunction(const IteratorType& myIterator)
{
    _ptr = &(*myIterator);
}
Festination answered 29/8, 2012 at 13:48 Comment(3)
Note that this will fail if the stored object overloads operator& (yes, you should not overload operator& yet it is allowed in the language)Favianus
No need for parentheses in &*myIterator.Playbill
C++20: std::to_address.Sigurd
H
30

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

Hagerman answered 29/8, 2012 at 13:49 Comment(3)
+1 for std::addressof. If there is no C++11, one can use boost::addressof.Festination
Only forward iterators promise to return references, input and output iterators can return proxy objects, which & is inappropriate for.Sublime
You must guarantee that whatever iterator you apply that to, must be valid. I.e. a non-end iterator. Otherwise... you know... demons.Niedersachsen
E
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.

Endaendall answered 29/8, 2012 at 13:49 Comment(1)
You must guarantee that whatever iterator you apply that to, must be valid. I.e. a non-end iterator. Otherwise... you know... demons.Niedersachsen
D
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.

Dampproof answered 24/6, 2021 at 10:23 Comment(1)
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.Ezarras

© 2022 - 2024 — McMap. All rights reserved.