Jump to content
  • Advertisement
Sign in to follow this  
Dragon_Strike

std::set design issue

This topic is 3338 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

im having a problem with std::set ive got different sets where all the types inherit a class "Identifiable" with an std::string Id() function... looks somehting like this
struct IDCompare	
{ 
bool operator()(const IdentifiablePtr& lhs, const IdentifiablePtr& rhs) const	
{ 
return strcmp(lhs->Id().c_str(), rhs->Id().c_str())  < 0 ; 
} 
};

std::set<boost::shared_ptr<SomeType>, IDCompare>

however when i want to find an object in the set based on the "Id" i get into problems...
			template<typename T> 
			boost::shared_ptr<T> Find(const std::string& id) const
			{
				boost::shared_ptr<T> dummy(new T(id));
				SetType::const_iterator it = mySet.find(dummy);
				return it != Get<T>().end() ? *it : boost::shared_ptr<T>();
			}

i have to create a "dummy" object of the type in order to find the real object... these objects can be pretty large so i dont want to create a dummy everytime... the reason im using a set instead of a map is that i want to be able to use for_each functions and similar easily... how shoudl i go about this?

Share this post


Link to post
Share on other sites
Advertisement
struct IDCompare
{
bool operator()(const IdentifiablePtr& lhs, const IdentifiablePtr& rhs) const
{
return lhs->Id() < rhs->Id();
}
bool operator()(const IdentifiablePtr& lhs, const std::string& rhs) const
{
return lhs->Id() < rhs;
}
bool operator()(const std::string& lhs, const IdentifiablePtr& rhs) const
{
return lhs < rhs->Id();
}
};
...
std::string str("hi");
mySet.find(str);

Share this post


Link to post
Share on other sites

return strcmp(lhs->Id().c_str(), rhs->Id().c_str()) < 0 ;


This would be somewhat simpler as:


return lhs->Id() < rhs->Id();


As to the dummy, at least it doesn't have to be allocated dynamically. But perhaps a map would be better (do the objects even need to know their ID if the map could know that?)

Share this post


Link to post
Share on other sites
Quote:
Original post by visitor

return strcmp(lhs->Id().c_str(), rhs->Id().c_str()) < 0 ;


This would be somewhat simpler as:


return lhs->Id() < rhs->Id();


As to the dummy, at least it doesn't have to be allocated dynamically. But perhaps a map would be better (do the objects even need to know their ID if the map could know that?)


i think a map would work better... however there are problems when i want to use algorithms on the collection... since the map iterator works on key value pairs... do u know of any adapters for maps?

Share this post


Link to post
Share on other sites
Quote:
Original post by Dragon_Strike
there are problems when i want to use algorithms on the collection... since the map iterator works on key value pairs
What kinds of problems? It's just that it seems relatively easy to extract the value from a key-value pair?

Share this post


Link to post
Share on other sites
Quote:
Original post by incin
struct IDCompare
{
bool operator()(const IdentifiablePtr& lhs, const IdentifiablePtr& rhs) const
{
return lhs->Id() < rhs->Id();
}
bool operator()(const IdentifiablePtr& lhs, const std::string& rhs) const
{
return lhs->Id() < rhs;
}
bool operator()(const std::string& lhs, const IdentifiablePtr& rhs) const
{
return lhs < rhs->Id();
}
};
...
std::string str("hi");
mySet.find(str);


that doesnt work...?

cannot convert parameter 1 from 'const std::string' to 'const boost::shared_ptr<T> &'

Share this post


Link to post
Share on other sites
Quote:
Original post by dmatter
Quote:
Original post by Dragon_Strike
there are problems when i want to use algorithms on the collection... since the map iterator works on key value pairs
What kinds of problems? It's just that it seems relatively easy to extract the value from a key-value pair?


well the problem is that it adds complexity and makes it harder to work with... id rather add some extra code here than having to extract the value with every use case

EDIT:

another reason i want the objects to know their ids is that i can optimize it later by precaluclating a hash function and use that for lookups rather than running a hash function for each lookup...

[Edited by - Dragon_Strike on May 2, 2009 4:11:07 PM]

Share this post


Link to post
Share on other sites
Sorry, thought I did that before. But it obviously won't work, as find() must take a value_type. I'd also vote for using a map. You can always use helper functions to hide the map implementation.

Share this post


Link to post
Share on other sites
You need to use the right container for the job, and when the key is logically separate from the value, you use a map.

In your case, the value "knows" about it's own key, which is OK, but the key is obviouslly still logically separate, since you want to be able to search just on key.

Share this post


Link to post
Share on other sites
Quote:

But it obviously won't work, as find() must take a value_type.


And I thought I had learned something new...

Probably to make it more efficient with a set, you can avoid the dynamic allocation because boost::shared_ptr can also hold pointers to stack objects.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!