Re: STL and finding objects by name
On 4 Apr., 15:37, Matthew Bucknall <m...@mattbucknall.com> wrote:
Apologies if the answer to this is obvious, I have spent quite some time
trying to come up with a solution. I would like to use some sorted STL
container (maybe a set ?) to hold a bunch of named objects, that is,
std::set would be one possible choice, yes.
objects that posses their own name. I then want to search for objects in
the container by name. Here is an example:
class Thing
{
public:
Thing(const std::string& name):
m_name(name)
{}
std::string get_name() const { return m_name; }
bool operator< (const Thing& rhs) const
{
return m_name < rhs.m_name;
}
private:
const std::string m_name;
};
Instances of this class cannot be used in std containers, because
they are not Assignable (due to the const data member m_name).
You have to remove the const qualifier.
std::set<Thing> things;
std::set<Thing>::iterator find_thing(const std::string& name)
{
// this won't work of course, but this hopefully illustrates
// what I want to do
return things.find(name);
}
Except for the failure that Thing is not Assignable, the code should
work.
It works, because Thing has an implicit c'tor accepting a std:string,
so
the code above does the "correct" thing by invoking
things.find(Thing(name));
If this too expensive for you, you should consider to use a cheap-
to-create ThingProxy instead of Thing in the set. This would mean that
the
actual data (e.g. the string member) is stored in an external
container.
In this case you have to ensure careful life-time control between the
set and the actual data container.
My question is, how can named objects (such as Thing) be stored in an
STL container such that they can then be efficiently found by name?
This is one possible choice. You can also use a (manually) sorted
sequence container, like std::vector<Thing>.
If Thing::operator< is not a natural sorting for Thing, you should
consider to separate the predicate from the value type:
struct ThingByName {
bool operator()(const Thing& lhs, const Thing& rhs) const
{
return lhs.get_name() < rhs.get_name();
}
};
typedef std::set<Thing, ThingByName> ThingSet;
You might consider to return a const reference in get_name(),
if invoking the predicate shows to be a performance blocker.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]