13

I may need to rethink my overall design a bit more, but as it stands, it looks like I may want to do something like:

class A; 
class B;
std::map<boost::shared_ptr<const A>, B> APtrToBMap;

I've tried this, and it does seem to work in a simple case (the compiler didn't complain, and simple tests seem to work). But I'm having second thoughts about this approach. I suspect there are some gotchas in there that I'm not aware of.

So, is the above valid in a practical sense? Or is there some flaw I'm not aware of when I do this?

skaffman
  • 398,947
  • 96
  • 818
  • 769
Taeolas
  • 265
  • 2
  • 7
  • 1
    @Sam, just because you haven't discovered a problem yet doesn't mean it's nonexistant. I think it's a great idea to ask about potential problems for a non-standard usage like this. – Mark Ransom Nov 10 '10 at 17:02
  • Thank you everyone for your responses. As some of you noted, it is mainly a symptom of a bad design; I was trying to solve a problem in the wrong place. I've since reexamined my design and won't need to do the bad map I questioned about. The responses as to why this is a bad idea too were really enlightening; I knew in my gut it wouldn't quite do what I was looking to do; I just couldn't see why until now. (In fact what I was trying to do wouldn't work with the map I templated above) – Taeolas Nov 10 '10 at 18:55

4 Answers4

24

The reference has this to say:

template<class T, class U>
  bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws

Returns: an unspecified value such that

  • operator< is a strict weak ordering as described in section 25.3 [lib.alg.sorting] of the C++ standard;
  • under the equivalence relation defined by operator<, !(a < b) && !(b < a), two shared_ptr instances are equivalent if and only if they share ownership or are both empty.

Throws: nothing.

Notes: Allows shared_ptr objects to be used as keys in associative containers.

UncleBens
  • 40,819
  • 6
  • 57
  • 90
4

Yes, you can use a shared pointer as the key for the std::map, but that is a sure sign of broken design. It would be ordered according to some random memory locations.

Your question is a bit vague. If you say how would you use that map and what are you trying to archive, you might get more useful answers.

BЈовић
  • 62,405
  • 41
  • 173
  • 273
  • 2
    A map with random ordering is still useful for quick lookup of data that is associated with but not part of the object. I wouldn't jump to the conclusion of a broken design. – Mark Ransom Nov 10 '10 at 16:58
  • @Mark Can you give an example? If the map's key is a pointer, then why the map's value is not part of the object? The effect is the same. – BЈовић Nov 10 '10 at 17:03
  • What if you want to search for data based on a particular object? I've used this quite a few times in attaching data to items in UI lists and such when the API didn't provide a reasonable method of doing so. – Edward Strange Nov 10 '10 at 17:18
  • @Noah Then write a wrapper. By doing so, you can also ease the unit testing of your code, because you can replace your objects with mock objects. – BЈовић Nov 10 '10 at 19:36
0

Careful if you're using this in conjunction with boost::python! All operations in C++ based on comparison of shared_ptr objects may fail if you pass in those shared_ptr objects from Python

0

I'm not 100% familiar with shared pointer, but if there is a way to get access to the original pointer, you can use that as the key (if you are still worried for some reason).

robev
  • 1,909
  • 3
  • 23
  • 32
  • But then the map wouldn't keep the shared_ptr from destroying itself. If you were to put the shared_ptr itself into the map, then you could make it such that the only reference to the ptr was found within the map. – Bill Lynch Nov 10 '10 at 16:52
  • I don't understand...he just wants a map of the pointer to the B object, so I said if he's afraid of using the shared ptr for some reason he can use the pointer itself. – robev Nov 10 '10 at 16:57
  • Or do you mean that having a copy of the shared_ptr in the map, it'll keep the object from being deleted? – robev Nov 10 '10 at 16:57
  • 1
    You can do this without having to STORE the raw pointer. You can store the shared pointer and override the comparison operator of the map. – Edward Strange Nov 10 '10 at 17:19