473,320 Members | 2,110 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

pointer to reference adaptor

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::operator* as an adaptor. But what if i
wanted to make code more generic and working with raw pointers too?

Regards,
Stanislaw

Jul 22 '05 #1
3 2246

"Stanislaw Salik" <s.*****@microgen.pl> wrote in message
news:ce**********@news.onet.pl...
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
Jul 22 '05 #2
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!
Jul 22 '05 #3
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::pointee<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::ostream_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::ostream_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::ostream_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::ostream_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::ostream_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::ostream_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::ostream_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::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;

return 0;
}
Jul 22 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Matthias Kaeppler | last post by:
Hello, I need to sort a range of pointers with a predicate which applies to the pointees. I tried to use boost::indirect_iterator, however, this will sort the container with the pointees instead...
110
by: Mr A | last post by:
Hi! I've been thinking about passing parameteras using references instead of pointers in order to emphasize that the parameter must be an object. Exemple: void func(Objec& object); //object...
1
by: Tony Johansson | last post by:
Hello! I'm reading about design pattern adaptor in the GOF book and there is something that sounds strange. When you use the adaptor design pattern you have these participants. *Target -...
0
by: Tony Johansson | last post by:
Hello!! This is about the adaptor design pattern. If you use the class adaptor its easy to override. It says an object adaptor makes it harder to override Adaptee behavior. It will require...
1
by: HIK | last post by:
I am trying to write a class which has a function that loads a dataset, and performs and xslt tranformtion on the dataset and returns the resulting string. In asp.net 1.1 I was able to do most...
1
by: | last post by:
Greetings All, I'm trying to access a excel file using the odbc data adaptor but the tables arent showing up. I can get connected to the excel file using the Wizard but when I go to do the odbc...
13
by: al.cpwn | last post by:
I get that these two are different int* get() { static int m; return &m; } int& get() {
5
by: StephQ | last post by:
This is from a thread that I posted on another forum some days ago. I didn't get any response, so I'm proposing it in this ng in hope of better luck :) The standard explanation is that pointer...
7
by: Neil | last post by:
What I am doing wrong This works batPointer = adaptors.adaptor->batData; adaptors.batteries = batPointer->battery; where: batData is a pointer to a struct batPointer is a pointer to a...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.