Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old January 12th, 2006, 08:45 AM
Simon Elliott
Guest
 
Posts: n/a
Default Converting iterator to pointers, revisited

I have some code where it's necessary to convert an iterator to a
pointer, to pass the pointer to a legacy function. I've been looking at
ways of encapsulating this, so I put together a short test app:

#include <vector>
#include <iostream>

int main (int argc, char *argv[])
{
std::vector<int> vi;
vi.push_back(1);
vi.push_back(2);
vi.push_back(3);
std::vector<int>::iterator ii = vi.begin();
int* pi = &*ii;
std::cout << "result:" << *pi << std::endl;
return(0);
}

I want to document and encapsulate the iterator to pointer conversion,
along these lines:

pi = iterator_to_pointer(ii);

*** Attempt#1

#define iterator_to_pointer(i) &*i

This works but it's an Evil Macro. (It should probably be parenthesised
a bit better but I don't want to go down this route so I haven't
bothered.)


*** Attempt#2

int* iterator_to_pointer(std::vector<int>::iterator i)
{
return(&*(i));
}

This works but it's insufficiently generic to be useful. The obvious
way forward is to make this a template:


*** Attempt#3

template<class T> typename T::value_type* iterator_to_pointer(typename
T::iterator i)
{
return(&*(i));
}

This template isn't matched by my line
pi = iterator_to_pointer(ii);

In g++: error: no matching function for call to
`iterator_to_pointer(__gnu_cxx::__normal_iterator< int*,
std::vector<int, std::allocator<int> > >&)'

I can't work out why this isn't matched. Any ideas?

BTW, I expect iterator_to_pointer() not to work with oddities such as
std::vector<bool> but it would be a nice bonus if it wouldn't compile
if someone tries to use it with std::vector<bool>.

--
Simon Elliott http://www.ctsn.co.uk
  #2  
Old January 12th, 2006, 09:35 AM
Ale¹ Pergl
Guest
 
Posts: n/a
Default Re: Converting iterator to pointers, revisited

> I have some code where it's necessary to convert an iterator to a[color=blue]
> pointer, to pass the pointer to a legacy function.
> ...
> std::vector<int>::iterator ii = vi.begin();
> int* pi = &*ii;[/color]

This is not a conversion of any sort. You are merely obtaining a reference
to the item in the vector that the iterator is positioned at and then getting
the address of that item and assigning it to pi. That's quite a normal way
of doing this kind of thing so I wouldn't bother with creating a specific
function for it.
[color=blue]
> *** Attempt#3
>
> template<class T> typename T::value_type* iterator_to_pointer(typename
> T::iterator i)
> {
> return(&*(i));
> }
> ...
> In g++: error: no matching function for call to
> `iterator_to_pointer(__gnu_cxx::__normal_iterator< int*,
> std::vector<int, std::allocator<int> > >&)'[/color]

The compiler is unable to deduce the template parameter T from what you are
providing as an argument to the function. You are providing vector<int>::iterator
but the compiler cannot figure out that you want T to be vector<int>. If
you really want to create a function like this (discouraged), do it like
this:

template<class T> typename T::pointer iterator_to_pointer(T& i)
{
return(&*(i));
}


  #3  
Old January 12th, 2006, 04:55 PM
fluidparody@yahoo.com
Guest
 
Posts: n/a
Default Re: Converting iterator to pointers, revisited

This one seems to work:

#include <iostream>
#include <vector>

template <typename T, typename I>
T* iterator_to_pointer(I i)
{
return (&(*i));
}

int main()
{
std::vector<int> vi;
vi.push_back(1);
vi.push_back(2);
vi.push_back(3);
std::vector<int>::iterator ii = vi.begin();

int *pi = iterator_to_pointer<int, std::vector<int>::iterator >
(ii);

std::cout << *pi << std::endl;

return 0;
}

  #4  
Old January 13th, 2006, 04:45 PM
Simon Elliott
Guest
 
Posts: n/a
Default Re: Converting iterator to pointers, revisited

On 12/01/2006, Ale¹ Pergl wrote:
[color=blue][color=green]
> > std::vector<int>::iterator ii = vi.begin();
> > int* pi = &*ii;[/color]
>
> This is not a conversion of any sort. You are merely obtaining a
> reference to the item in the vector that the iterator is positioned
> at and then getting the address of that item and assigning it to pi.
> That's quite a normal way of doing this kind of thing so I wouldn't
> bother with creating a specific function for it.[/color]

Fair enough. I want to reduce the maintenace burden, but if it's fairly
commonplace and well understood, perhaps I won't bother.
[color=blue]
> The compiler is unable to deduce the template parameter T from what
> you are providing as an argument to the function. You are providing
> vector<int>::iterator but the compiler cannot figure out that you
> want T to be vector<int>. If you really want to create a function
> like this (discouraged), do it like this:
>
> template<class T> typename T::pointer iterator_to_pointer(T& i)
> {
> return(&*(i));
> }[/color]

The iterator::pointer type seems to be patchily documented (eg it's not
in the docs for my compiler, BCB6). Is it a fairly new/non standard
feature?

--
Simon Elliott http://www.ctsn.co.uk
  #5  
Old January 13th, 2006, 06:15 PM
Stephan Brönnimann
Guest
 
Posts: n/a
Default Re: Converting iterator to pointers, revisited

Simon Elliott wrote:
[color=blue]
>
> The iterator::pointer type seems to be patchily documented (eg it's not
> in the docs for my compiler, BCB6). Is it a fairly new/non standard
> feature?
>
> --
> Simon Elliott http://www.ctsn.co.uk[/color]

IIRC from Bjarne Stroustrup iterators are implementation specific
(thus the surprising error message in the original post):
you only can rely on their semantics.

Regards, Stephan
broeni@osb-systems.com
Open source rating and billing engine for communication networks.

  #6  
Old January 14th, 2006, 01:15 PM
Bo Persson
Guest
 
Posts: n/a
Default Re: Converting iterator to pointers, revisited


"Simon Elliott" <Simon at ctsn.co.uk> skrev i meddelandet
news:43c7d601$0$87299$bed64819@news.gradwell.net.. .[color=blue][color=green]
>>
>> template<class T> typename T::pointer iterator_to_pointer(T& i)
>> {
>> return(&*(i));
>> }[/color]
>
> The iterator::pointer type seems to be patchily documented (eg it's
> not
> in the docs for my compiler, BCB6). Is it a fairly new/non standard
> feature?[/color]

The formally correct way to access the pointer type is

typename std::iterator_traits<T>::pointer

which might be equivalent to T::pointer, but doesn't have to be.


Bo Persson


 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles