Question

I have two options to create a std map. I can work with both the types of map.

1.    std::map<A, std::string>    
2.    std::map<A*, std::string>

where A is a class object

Later in the code I will have to perform a find operation.

1.    std::map<A, std::string>   myMap1;
          if(myMap1.find(A_obj) != myMap1.end())
          {
          }

2.    std::map<A*, std::string>   myMap2;
          if(myMap2.find(A_obj_ptr) != myMap2.end())
          {
          }

I want to know which one is recommend to create. In which of these two, would I not have to overload any operators in class A for find operation to work. Which of these would have problems on insert operation when any operators are not overloaded.

If it helps, this is class A

class A
{
    private:
        std::vector<std::string> m_member;

    public:
        A(std::vector<std::string> input);  
};
Was it helpful?

Solution

Note that these two samples are only functionally equivalent if A instances are singletons. Otherwise it's very possible that two A values which are equal in value but different in address. This would lead to different semantics.

Personally I prefer the std::map<A, std::string> version because the semantics of it are crystal clear. The keys have equality semantics and there is no potentially for a dangling or nullptr value. The std::map<A*, std::string> version comes with a host of questions for the developer looking through the code

  • Who owns the key values?
  • Are all instances of A singletons? If not how do I ensure the A I'm looking for is the A* value that is stored?
  • When are the keys freed?

OTHER TIPS

First option is preferable. For second option, we need to make sure that keys (pointers here) are protected. May be shared pointers will help. Other issue is that the map will be shorted w.r.t. the address of the A objects and that might not be very useful. Below sample demonstrates how the comparator can be defined or the default comparator can be overridden:

class A 
{
public:
    int a;  
};

namespace std 
{
   template<> 
   struct less<A*>
   {
    bool operator()(const A* const a, const A*  const b) const{
        return a->a < b->a;

   }
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top