Creating a std::map of references

R

relain

Hi,
I was hoping to use to replace a map of pointers to objects with a map
of references instead, since the pointers way of doing what i want to
do is proving to be a bit tiresome. I'm still pretty new to C++ but i
know that a reference itself is no object, and so you can't stuff it
into a container. I came upon the boost::reference_wrapper template
and although i had success with using this in a std::vector i have no
luck with a map. If i understand the compiler errors this is because
there's no default constructor for reference_wrapper<thing> which
seems to be sensible, how can you have a reference to a non thing?

So my questions are:

1 - Have i just boobed and not actually understood the output from the
compiler?

2 - If i haven't should i inherit reference_wrapper and bodge it up to
make it work, with some kind of default container with something like
a NULL reference, this is bad because then really im just using
pointers. Is there a better way? Or should i just turn back to the C-
side and make my pointers work.

the test code i was using to play around with it is:

######

#include <map>
#include <iostream>
#include <boost/ref.hpp>

class test_content{
public:
test_content(int my_id){id = my_id;};
int id;
};


struct ltstr{
public:
bool operator()(int thing1, int thing2){
if (thing1 < thing2){
return(true);
} else {
return(false);
}
}

};


int main (void){
std::map<int, boost::reference_wrapper<test_content>, ltstr>
the_map;
test_content test_thing(5);
the_map[3] = boost::reference_wrapper<test_content>(test_thing);
return(0);
}

######

And g++ (4.0.1 darwin) says:

[reiko:test]:g++ maptest.cpp -I /usr/local/boost_1_34_0/
/usr/include/c++/4.0.0/bits/stl_map.h: In member function '_Tp&
std::map<_Key, _Tp, _Compare, _Alloc>::eek:perator[](const _Key&) [with
_Key = int, _Tp = boost::reference_wrapper<test_content>, _Compare =
ltstr, _Alloc = std::allocator<std::pair<const int,
boost::reference_wrapper<test_content> > >]':
maptest.cpp:30: instantiated from here
/usr/include/c++/4.0.0/bits/stl_map.h:339: error: no matching function
for call to
'boost::reference_wrapper<test_content>::reference_wrapper()'
/usr/local/boost_1_34_0/boost/ref.hpp:43: note: candidates are:
boost::reference_wrapper<T>::reference_wrapper(T&) [with T =
test_content]
/usr/local/boost_1_34_0/boost/ref.hpp:33: note:
boost::reference_wrapper<test_content>::reference_wrapper(const
boost::reference_wrapper<test_content>&)



thanks!
 
V

Victor Bazarov

relain said:
I was hoping to use to replace a map of pointers to objects with a map
of references instead, since the pointers way of doing what i want to
do is proving to be a bit tiresome. I'm still pretty new to C++ but i
know that a reference itself is no object, and so you can't stuff it
into a container. I came upon the boost::reference_wrapper template
and although i had success with using this in a std::vector i have no
luck with a map. If i understand the compiler errors this is because
there's no default constructor for reference_wrapper<thing> which
seems to be sensible, how can you have a reference to a non thing?

So my questions are:

1 - Have i just boobed and not actually understood the output from the
compiler?

No, you got it right.
2 - If i haven't should i inherit reference_wrapper and bodge it up to
make it work, with some kind of default container with something like
a NULL reference, this is bad because then really im just using
pointers. Is there a better way? Or should i just turn back to the C-
side and make my pointers work.

You don't need a default constructor for the type you store in 'map'
if you never use the indexing operator with keys that don't exist.

the test code i was using to play around with it is:

######

#include <map>
#include <iostream>
#include <boost/ref.hpp>

class test_content{
public:
test_content(int my_id){id = my_id;};
int id;
};


struct ltstr{
public:
bool operator()(int thing1, int thing2){
if (thing1 < thing2){
return(true);
} else {
return(false);
}
}

};


int main (void){
std::map<int, boost::reference_wrapper<test_content>, ltstr>
the_map;
test_content test_thing(5);
the_map[3] = boost::reference_wrapper<test_content>(test_thing);

Don't do that. Do

the_map.insert(make_pair(3, test_thing));
return(0);
}

######

And g++ (4.0.1 darwin) says:

[..]

V
 
R

relain

I see, the problem then would appear to be (after a little fiddling)
that if you want to look something up and it's not there. What should
map.find return in this case? An iterator pointing to nothing?

Thanks for the help!
 
V

Victor Bazarov

relain said:
I see, the problem then would appear to be (after a little fiddling)
that if you want to look something up and it's not there. What should
map.find return in this case? An iterator pointing to nothing?

If it doesn't find it, it returns 'end()'.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top