Re: constraints on types used for instantiating standard containers
On Mar 9, 8:51 am, Sebastian Redl <e0226...@stud3.tuwien.ac.at> wrote:
On Thu, 8 Mar 2007, Lance Diduck wrote:
You can even have
runtime values inside the comparator objects:
struct Comp2{
int v;
Comp2(int _v):v(_v){}
bool operator()(MyKey const&l,MyKey const&r)const{
return l.val.size()+v<r.val.size();
}
};
Except of course that this comparator does not define a strict weak
ordering if passed a negative value. (comp(a, b) == true, and also for b-a
< abs(v) comp(a, b) == true && comp(b, a) == true)
As you said, the real business is in the comparator.
Sebastian Redl
yes -- on the train home about an hour after I made that post the "Oh %
$&#^" moment hit me. I stand corrected. Thanks:
To belabor the point you could do this:
struct mycomp{
int v;
mycomp(int _v):v(_v){}
bool operator()(MyKey const&l,MyKey const&r){
if(v==0)return &l<&r;//ordered by where they live in memory
// this one may give you headaches though,
// since the object can move around inside an associative container
// in some implementations
// but it does meet the requirement
if(v==1)return l.size()<r.size();//ordered by size
if(v==2)return r.val <l.val;//ordered reverse
return l.val<r.val;//ordered by strings operator<
}
};
Of course, the container prohibits you from modifying the comparator
object once it is set inside the container.
Here is a more useful example that works using a collator
struct collcmp{
std::locale loc??
collcmp(std::locale const&_a=std::locale()):loc(_a){}
bool operator()(std::string const&lhs,
std::string const&rhs)const{
return 0>loc(lhs,rhs)??
}
}??
typedef std::set<std::string,collcmp> collator??
collator(collcmp(std::locale("de"))) german??
collator(collcmp(std::locale("fr"))) french??
It is easy to see how to make this case-insensitive, or depend on your
Mom's birthday if needed.
The standard even defines what happens if you do this:
german=french;//See 23.1.2
So the moral is the real brains are in the comparator. You can make
the Key class itself no smarter than an ameoba. All it has to do is
live, die, and replicate. It does not even have to store a value, if
you wanted to make a trivial associative container that can only store
a single element.
But I have always found it to be more convenient to just make an
operator< within the key class itself -- the users and maintainers of
the subsequent code do not have to them be experts on associative
containers or define comparator objects. Many C++ users dont even know
you can define comparator objects. So in practical terms the Key class
should define an operator< that is a strict weak ordering.
But it is not required, and that is why the standard does not mention
it.
Lance
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]