title: Should I use a map or a set if my key is part of my value?
body: <p>In C++, I have an class which is ordered by its name which is a <code>std::string</code>.  I wish to only have one per each unique name in either a <code>std::map</code> or <code>std::set</code>.</p>
  
  <p>I could use a <code>std::set</code> since the <code>operator&lt;</code> will order my instances by their name, however, I need to lookup an instance by its name.  Using a map where the key is the name is straight forward, however, I could also use a set and construct a dummy instance of my class with the name I wish to lookup to locate in the set the actual instance of the class for the given name.</p>
  
  <p>I imagine I should just go with the map to make the code straight forward, but wonder if there might be a way to go with the set since the key is effectively part of my object anyway and thus avoid some redundancy.</p>
  
  <p>Is there a way to use the set and be able to locate objects by their key in a clean way or should I just use a map and be done with it?</p>
  
  <p>Here is the class to be inserted (in draft form) and in each directory there is either a set or map of Node(s) keyed off the Node's name:</p>
  
  <pre><code>class Node {
  public:
    Node(Directory &amp;parent, const std::string &amp;name)
      : _name(name),
        _parent(&amp;parent),
        _isRoot(false) {
      if (name.empty()) {
        throw InvalidNodeNameError(name);
      }
    }
  
  protected:
    // This is only used for the root directory:
    Node()
      : _name(""),
        _parent(0),
        _isRoot(true) {
    }
    Node(const std::string &amp;name)
      : _name(name),
        _parent(0),
        isRoot(false) {
    }
  
  public:
    virtual ~Node() {
      if (parent()) {
        parent()-&gt;remove(*this);
      }
    }
  
    bool operator&lt;(const Node &amp;rhs) const {
      return _name &lt; rhs._name;
    }
  
    Directory *parent() const {
      return _parent;
    }
    void setParent(Directory *parent) {
      _parent = parent;
    }
  
    const std::string &amp;name() const {
      return _name;
    }
  
    bool isRoot() const {
      return _isRoot;
    }
  
    std::string pathname() const {
      std::ostringstream path;
  
      if (parent()) {
        path &lt;&lt; parent()-&gt;pathname() &lt;&lt; '/';
      } else {
        path &lt;&lt; '/';
      }
      path &lt;&lt; name();
  
      return path.str();
    }
  
  private:
    // Not defined:
    Node(const Node &amp;rhs);
    Node &amp;operator=(const Node &amp;rhs);
  
  private:
    std::string  _name;
    Directory   *_parent;
    const bool   _isRoot;
  
  };
  </code></pre>