Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why BOOST_FOREACH cannot handle const boost::ptr_map?

Tags:

c++

foreach

boost

void main()
{
  typedef boost::ptr_map<int, char>  MyMap;
  //typedef std::map<int, char *>  MyMap;  // in contrast with std type it works

  MyMap mymap;

  mymap[1] = new char('a');
  mymap[2] = new char('b');
  mymap[3] = new char('c');

  BOOST_FOREACH(MyMap::value_type value, mymap)
  {
    std::cout << value.first << "  " << value.second << std::endl;
  }

  MyMap const & const_mymap = mymap;

  BOOST_FOREACH(const MyMap::value_type value, const_mymap)
  {
    std::cout << value.first << "  " << value.second << std::endl;
  }
}

The following error message comes from GCC at the second BOOST_FOREACH

error: conversion from 'boost::ptr_container_detail::ref_pair<int, const char* const>' to non-scalar type 'boost::ptr_container_detail::ref_pair<int, char* const>' requested

I reckon that this is the weakness of the pointer container's ref_pair...

like image 592
psaghelyi Avatar asked Apr 13 '10 13:04

psaghelyi


2 Answers

Based on this answer, it looks like you're right. But there's a workaround. Change your second loop to this:

BOOST_FOREACH(MyMap::const_iterator::value_type value, const_mymap)
{
    std::cout << value.first << "  " << value.second << std::endl;
}
like image 143
Michael Kristofik Avatar answered Oct 07 '22 07:10

Michael Kristofik


Typedefing is also confusing when using maps. Its much simpler(and much more readable) to use a tuple instead. Here's how you can use a tuple:

int key;
char* value;
BOOST_FOREACH(boost::tie(key, value), mymap)
{
  std::cout << key << "  " << value << std::endl;
}

Plus, you can give more meaningful names instead of value.first and value.second.

like image 34
Paul Fultz II Avatar answered Oct 07 '22 06:10

Paul Fultz II