Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > pointer to reference adaptor

Reply
Thread Tools

pointer to reference adaptor

 
 
Stanislaw Salik
Guest
Posts: n/a
 
      07-30-2004
Hi,

Lets suppose we want to use generic algotithms on collections of
pointers (both raw and smart). For example, we want to sort a vector of
(smart)pointers. We need a comparator that will take two pointers and
return a bool.

std::vector<std::string *> v;
std::sort(v.begin(), v.end(), std::less<int>());

The code above will noc compile, since std::less<std::string>() object
takes two strings, while we have pointers to std::string. So we need an
adaptor.

template <class T, class U>
struct pointer_to_ref
{
typedef T argument_type;
typedef U result_type;

inline
result_type & operator() (argument_type obj)
{
return *obj;
}
};

std::vector<int *> v;
std::sort(v.begin(), v.end(),
boost::bind(std::less<string>(),
boost::bind (pointer_to_ref<std::string*, std::string>(),_1),
boost::bind (pointer_to_ref<std::string*, std::string>(),_2)));

And the code will just work fine.

And here goes my question. Since there are so many places where
pointer_to_ref (and pointer_to_value probably) would be useful, is there
any standard class that does the same thing?

For example, for smart pointers i can use
&collection_type::value_type:perator* as an adaptor. But what if i
wanted to make code more generic and working with raw pointers too?

Regards,
Stanislaw

 
Reply With Quote
 
 
 
 
Jonathan Turkanis
Guest
Posts: n/a
 
      07-30-2004

"Stanislaw Salik" <(E-Mail Removed)> wrote in message
news:cecujk$boi$(E-Mail Removed)...
> Hi,
>
> Lets suppose we want to use generic algotithms on collections of
> pointers (both raw and smart). For example, we want to sort a vector

of
> (smart)pointers. We need a comparator that will take two pointers

and
> return a bool.


<snip>

> template <class T, class U>
> struct pointer_to_ref
> {
> typedef T argument_type;
> typedef U result_type;
>
> inline
> result_type & operator() (argument_type obj)
> {
> return *obj;
> }
> };


> And here goes my question. Since there are so many places where
> pointer_to_ref (and pointer_to_value probably) would be useful, is

there
> any standard class that does the same thing?


First, for the example you gave -- which is a common situation -- you
should be able to use indirect_iterators
(http://www.boost.org/libs/iterator/d..._iterator.html)

Second, I don't think it's necessary to have two template parameters.
You should be able to calculate the result type given the argument
type (see http://www.boost.org/boost/pointee.hpp.)

Jonathan


 
Reply With Quote
 
 
 
 
Stanislaw Salik
Guest
Posts: n/a
 
      07-30-2004

> First, for the example you gave -- which is a common situation -- you
> should be able to use indirect_iterators
> (http://www.boost.org/libs/iterator/d..._iterator.html)
>
> Second, I don't think it's necessary to have two template parameters.
> You should be able to calculate the result type given the argument
> type (see http://www.boost.org/boost/pointee.hpp.)


Thanks a lot!
 
Reply With Quote
 
Stanislaw Salik
Guest
Posts: n/a
 
      07-30-2004
Thanks for the information.

Jonathan Turkanis wrote:

> First, for the example you gave -- which is a common situation -- you
> should be able to use indirect_iterators
> (http://www.boost.org/libs/iterator/d..._iterator.html)


The indirect_iterator adaptor works fine. However, the resulting
algorithm is a bit different. With indirect_iterator, std::sort works on
objects (in this case integers), while the approach with
pointer_to_reference adaptors works on (smart)pointers.

In the example1.cpp below outputs

vect: 8 0 5 9 1 6 3 4 7 2
copy: 0 1 2 3 4 5 6 7 8 9
vect: 0 1 2 3 4 5 6 7 8 9
copy: 0 1 2 3 4 5 6 7 8 9


vect: 6 1 7 4 2 0 8 5 9 3
copy: 0 1 2 3 4 5 6 7 8 9
vect: 0 1 2 3 4 5 6 7 8 9
copy: 5 1 4 9 3 7 0 2 6 8

Notice that the copy becomes permuted while the original was sorted.

Is there a way to use indirect_iterator in such way that sort replaces
pointers instead of pointed values?

Jonathan Turkanis wrote:

> Second, I don't think it's necessary to have two template parameters.
> You should be able to calculate the result type given the argument
> type (see http://www.boost.org/boost/pointee.hpp.)


This makes the code a bit cleaner. Is there a way to create adaptor
object straight from the pointee<> template? Or is it still necessary to
declare structure that does the trick?

Regards,
Stanislaw

example1.cpp

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

#include <stdlib.h>

#include <boost/iterator/indirect_iterator.hpp>
#include <boost/bind.hpp>

template <class T>
struct pointer_to_ref
{
typedef T argument_type;
typedef typename boost:ointee<T>::type & result_type;

inline
result_type operator() (argument_type obj)
{
return *obj;
}
};

struct counter
{
typedef int* result_type;

counter () :n (0) {}
result_type operator() () { return new int (n++); }

int n;
};

typedef std::vector<int *> vector_t;


int
main ()
{
srand(time(0));

vector_t v;

std::generate_n (std::back_insert_iterator<vector_t>(v), 10,
counter());

vector_t w (v);

std::random_shuffle (v.begin(), v.end());

std::cout << "vect: ";
std::copy (boost::make_indirect_iterator(v.begin()),
boost::make_indirect_iterator(v.end()),
std:stream_iterator<int>(std::cout, " "));
std::cout << std::endl;

std::cout << "copy: ";
std::copy (boost::make_indirect_iterator(w.begin()),
boost::make_indirect_iterator(w.end()),
std:stream_iterator<int>(std::cout, " "));
std::cout << std::endl;

std::sort (v.begin(),
v.end(),
boost::bind(std::less<int>(),

boost::bind(pointer_to_ref<vector_t::value_type>() , _1),

boost::bind(pointer_to_ref<vector_t::value_type>() , _2)));

std::cout << "vect: ";
std::copy (boost::make_indirect_iterator(v.begin()),
boost::make_indirect_iterator(v.end()),
std:stream_iterator<int>(std::cout, " "));
std::cout << std::endl;

std::cout << "copy: ";
std::copy (boost::make_indirect_iterator(w.begin()),
boost::make_indirect_iterator(w.end()),
std:stream_iterator<int>(std::cout, " "));
std::cout << std::endl;

return 0;
}



example2.cpp:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

#include <stdlib.h>

#include <boost/iterator/indirect_iterator.hpp>


struct counter
{
typedef int* result_type;

counter () :n (0) {}
result_type operator() () { return new int (n++); }

int n;

};

typedef std::vector<int *> vector_t;

int
main ()
{
srand(time(0));

vector_t v;

std::generate_n (std::back_insert_iterator<vector_t>(v), 10,
counter());

vector_t w (v);

std::random_shuffle (v.begin(), v.end());

std::cout << "vect: ";
std::copy (boost::make_indirect_iterator(v.begin()),
boost::make_indirect_iterator(v.end()),
std:stream_iterator<int>(std::cout, " "));
std::cout << std::endl;

std::cout << "copy: ";
std::copy (boost::make_indirect_iterator(w.begin()),
boost::make_indirect_iterator(w.end()),
std:stream_iterator<int>(std::cout, " "));
std::cout << std::endl;

std::sort (boost::make_indirect_iterator(v.begin()),
boost::make_indirect_iterator(v.end()),
std::less<int>());

std::cout << "vect: ";
std::copy (boost::make_indirect_iterator(v.begin()),
boost::make_indirect_iterator(v.end()),
std:stream_iterator<int>(std::cout, " "));
std::cout << std::endl;

std::cout << "copy: ";
std::copy (boost::make_indirect_iterator(w.begin()),
boost::make_indirect_iterator(w.end()),
std:stream_iterator<int>(std::cout, " "));
std::cout << std::endl;

return 0;
}


 
Reply With Quote
 
 
 
Reply

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 On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Pointer to pointer or reference to pointer A C++ 7 07-05-2011 07:49 PM
Reference counting and API (const reference vs pointer oriented) mathieu C++ 8 08-31-2008 09:05 AM
reference and pointer-reference kasthurirangan.balaji@gmail.com C++ 4 12-24-2007 09:05 PM
Pointer-to-pointer-to-pointer question masood.iqbal@lycos.com C Programming 10 02-04-2005 02:57 AM
Passing the value by reference is same as pointer by reference sam pal C++ 3 07-16-2003 09:14 PM



Advertisments