Is there any way to convert a vector::iterator
into a pointer without having access to the vector itself? This works only if the vector
is available:
typedef vector<int> V;
int* to_pointer1( V& v, V::iterator t )
{
return v.data() + (t-v.begin() );
}
But how can this be done without having the vector
around? This wouldn't work:
int* to_pointer2( V::iterator t )
{
// the obvious approach doesn't work for the end iterator
return &*t;
}
In fact I would have expected this to be a very basic and popular question but for some reason I couldn't find it.
In general you are not guaranteed that there is a pointer corresponding to an iterator that refers to an ordinary vector item.
In particular std::vector<bool>
is specialized so that &*it
won't even compile.
However, for other vectors it's only1 the formally-pedantic that stops you from doing &*it
also for the end iterator. In C99 it is, as I recall, formally valid to do &*p
when p
is an end pointer, and a goal of std::vector
is to support all ordinary raw array notation. If I needed this I would just ignore the formal-pedantic, and write code with a view towards some future revision of the standard that would remove that imagined obstacle.
So, in practice, just do &*it
. :)
#include <iostream>
#include <vector>
using namespace std;
auto main() -> int
{
vector<int> x( 5 );
cout << &*x.begin() << " " << &*x.end() << endl;
cout << &*x.end() - &*x.begin() << endl; // Works nicely IN PRACTICE.
}
But do remember that you can't do this for vector<bool>
.
1) In a comment elsewhere user pentadecagon remarks: “Try -D_GLIBCXX_DEBUG
, as documented here: gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode_using.html.” g++ often provides some means of bringing any formal UB to the front, e.g. “optimization” of formally UB loops. A solution in this particular case is simply to not ask it to do this, but more generally one may have to explicitly ask it to not do it.
No, this is not currently possible. n3884 Contiguous Iterators: A Refinement of Random Access Iterators proposes a free function std::pointer_from
which would satisfy your requirement:
Expression:
std::pointer_from(a)
Return type:reference
Operational semantics: ifa
is dereferenceable,std::address_of(*a)
; otherwise, ifa
is reachable from a dereferenceable iteratorb
,std::pointer_from(b) + (a – b)
; otherwise a valid pointer value ([basic.compound]).
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