Re: Assignment operator, templates, double associative container
Ulrich Eckhardt wrote:
mscava@gmail.com wrote:
stl_algo.h:1076: error: non-static const member `const std::string
DataMapPair::first', can't use default assignment operator
Here's my code:
typedef std::map< std::string,
std::pair< bool, CountedPtr<T> > >
DataMap;
typedef std::pair< std::string,
std::pair< bool, CountedPtr<T> > >
DataMapPair;
First thing here: you might want to replace the second typedef with
typedef DataMap::element_type DataMapPair;
You mean DataMap::value_type, of course. (Logically, of course,
the value_type of the map would be just std::pair< bool,
CountedPtr<T> >. And element_type would be what you seem to
expect, rather than not exist at all. But in keeping with the
tradition that a function named remove reshuffles, while leaving
the same number of elements in the container...:-)
although, and that might make the difference, maps use a const key as
first
type to pair, so it would be a 'pair<string const, pair<...> >'.
DataMap dataMap_;
template <typename T> bool DataManager<T> ::
IsGarbage( const DataMapPair& dmPair )
I think the '<T>' is wrong after DataManager.
template <typename T> void DataManager<T> ::
CollectGarbage()
{
dataMap_.erase( remove_if( dataMap_.begin(), dataMap_.end(),
IsGarbage ), dataMap_.end() );
}
Can anyone tell how should I oveload that operator=? Or should I do
something else?
Okay, take a look at remove_if(). It reorders the elements so that the
non-fitting elements go to the end. However, you can't reorder the content
of a map, as it internally sorts it and needs that order! Hence also the
use of a const key type.
Actually, it would make a lot of sense for set and map to have a
remove_if member function, much in the way list does.
Typical solution:
it = map.begin();
while(it!=map.end())
if( predicate(*it))
map.erase(it++);
else
++it;
Note the use of the postfix increment operator. This works for all
containers where erasing in the middle doesn't invalidate iterators, i.e.
all except deque and vector.
According to the latest draft:
it = map.begin() ;
while ( it != map.end() ) {
if ( predicate( *it ) ) {
it = map.erase( it ) ;
} else {
++ it ;
}
}
should work with all containers. Of course, it's probable that
not all compilers implement this yet.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientie objet/
Beratung in objektorientierter Datenverarbeitung
9 place Simard, 78210 St.-Cyr-l'Icole, France, +33 (0)1 30 23 00 34
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]