title: Why is std::set allowing me to insert repeated (non-unique) custom elements?
body: <p>I need to create a collection of custom items that:</p>
  <ol>
  <li>Are ordered by priority</li>
  <li>Can't have repeated names.</li>
  </ol>
  <p>In this example, I am using <strong>std::set</strong> with an overloaded <strong>operator&lt;( )</strong>.As far as I know, <strong>std::set</strong> uses the <strong>operator&lt;( )</strong> both for ordering and for uniqueness check. But my code is failing, as I am able to insert items with repeated names:</p>
  <pre><code>#include &lt;iostream&gt;
  #include &lt;set&gt;
  
  
  
  struct Item
  {
      std::string name;
      int priority;
  };
  
  
  
  bool operator&lt;( const Item&amp; a, const Item&amp; b ) 
  {
      // Always returns false if names are equal.
      // Set should consider elements equal when a &lt; b is false and b &lt; a is also false.
      if( a.name == b.name )
          return false;
  
      return ( a.priority &lt; b.priority );
  }
  
  
  
  int main()
  {
      Item a  { &quot;a&quot;, 3000 };
      Item b  { &quot;b&quot;, 4000 };
      Item c  { &quot;c&quot;, 2000 };
      Item a2 { &quot;a&quot;, 5000 };
  
  
      std::set&lt;Item&gt; pool;
  
  
      pool.insert( a );
      pool.insert( b );
      pool.insert( c );
      pool.insert( a2 );
  
  
      for( const auto&amp; item : pool )
          std::cout &lt;&lt; item.name &lt;&lt; &quot;: &quot; &lt;&lt; item.priority &lt;&lt; std::endl;
  
  
      return 0;
  }
  </code></pre>
  <p>Compiling this in onlinegdb.com gives me the result below.</p>
  <p>Both elements with the name &quot;a&quot; are inserted into the <strong>std::set</strong>.</p>
  <pre><code>c: 2000
  a: 3000
  b: 4000
  a: 5000
  </code></pre>
  <p>What am I doing wrong?</p>
  <p>Should I use a different container?</p>
  <p><strong>EDIT:</strong></p>
  <p>Changing the insert order makes the code work as expected.</p>
  <pre><code>    pool.insert( a );
      pool.insert( a2 );
      pool.insert( b );
      pool.insert( c );
  </code></pre>
  <p>Correctly results in:</p>
  <pre><code>c: 2000
  a: 3000
  b: 4000
  </code></pre>