Why does my std::set find() not work?
<p>I have the following function and cannot figure out why it is not working.</p>

<p>Parameters are a set of Nonterminals and a vector of GrammarSymbol* (a word). Nonterminal is a subclass of GrammarSymbol. The function is supposed to filter all Nonterminals that are contained in the word as well as in the Nonterminal set and return them in a set.</p>

<pre><code>std::set&lt;Nonterminal&gt; Filter(const std::set&lt;Nonterminal&gt;&amp; symbolSet, const std::vector&lt;GrammarSymbol*&gt; w){

  //resulting set
  std::set&lt;Nonterminal&gt; rSet;

  std::vector&lt;GrammarSymbol*&gt;::const_iterator wit;
  std::set&lt;Nonterminal&gt;::const_iterator ntit;

  //iterate over all symbols of the word
  for(wit = w.begin(); wit != w.end(); wit++){

    //test if current symbol is a nonterminal
    const Nonterminal* nt = dynamic_cast&lt;const Nonterminal*&gt;(*wit);
    if(nt != NULL){
      std::cout &lt;&lt; "current symbol " &lt;&lt; nt-&gt;Str() &lt;&lt; " is nonterminal" &lt;&lt; std::endl;

      for(ntit = symbolSet.begin(); ntit != symbolSet.end(); ntit++){
        std::cout &lt;&lt; ntit-&gt;Str() &lt;&lt; "  " &lt;&lt; (!(*ntit &lt; *nt) &amp;&amp; !(*nt &lt; *ntit))&lt;&lt; std::endl;
      }
      //look for the symbol in the nonterminal set
      ntit = symbolSet.find(*nt);

      //if the symbol was found, insert it into resulting set
      if(ntit != symbolSet.end()){
        rSet.insert(*ntit);
        std::cout &lt;&lt; "inserted " &lt;&lt; ntit-&gt;Str() &lt;&lt; "into set, size: " &lt;&lt; rSet.size() &lt;&lt; std::endl;
      }
      else{
        std::cout &lt;&lt; "not found in symbolSet" &lt;&lt; std::endl;
      }
    }
  }
  return rSet;
}
</code></pre>

<p>This yields the output</p>

<pre><code>current symbol (1, 2, 2) is nonterminal
(1, 2, 2)  1
(2, 3, 3)  0
(3, 2)  0
(4, 3)  0
(5, 3, 1)  0
not found in symbolSet
</code></pre>

<p>It works just fine if I don't rely on the filter function and filter on my own:</p>

<pre><code>std::set&lt;Nonterminal&gt; Filter(const std::set&lt;Nonterminal&gt;&amp; symbolSet, const std::vector&lt;GrammarSymbol*&gt; w){

  //resulting set
  std::set&lt;Nonterminal&gt; rSet;

  std::vector&lt;GrammarSymbol*&gt;::const_iterator wit;
  std::set&lt;Nonterminal&gt;::const_iterator ntit;

  //iterate over all symbols of the word
  for(wit = w.begin(); wit != w.end(); wit++){

    //test if current symbol is a nonterminal
    const Nonterminal* nt = dynamic_cast&lt;const Nonterminal*&gt;(*wit);
    if(nt != NULL){
      std::cout &lt;&lt; "current symbol " &lt;&lt; nt-&gt;Str() &lt;&lt; " is nonterminal" &lt;&lt; std::endl;

      for(ntit = symbolSet.begin(); ntit != symbolSet.end(); ntit++){
        std::cout &lt;&lt; ntit-&gt;Str() &lt;&lt; "  " &lt;&lt; (!(*ntit &lt; *nt) &amp;&amp; !(*nt &lt; *ntit))&lt;&lt; std::endl;
        if(!(*ntit &lt; *nt) &amp;&amp; !(*nt &lt; *ntit)){
          rSet.insert(*ntit);
        }
      }
    }
  }
  return rSet;
}
</code></pre>

<p>Can anyone explain to me what happens here? As far as I know, std::set is supposed to compare elements with the operator&lt;. Comparing seems to work just fine, as shown by the output. </p>

<p>I would just continue with the selfmade filter, but I fear there is a bigger underlying problem.</p>

<p>Thanks!</p>

<p>Edit: Nonterminal and operator&lt; for Nonterminal:</p>

<pre><code>class Nonterminal : public GrammarSymbol{

  public: 

  /** The start state*/
  Idx mStartState;
  /** The stack symbol*/
  Idx mOnStack;
   /** The end state */
  Idx mEndState;
  //...
  }
</code></pre>

<p>Idx is just a typedef for an int.</p>

<pre><code>bool Nonterminal::operator&lt;(const GrammarSymbol&amp; other) const{
  if(typeid(*this) != typeid(other)) return true; //other is a terminal
  const Nonterminal&amp; nt = dynamic_cast&lt;const Nonterminal&amp;&gt;(other); //other is a nonterminal
  if (mStartState &lt; nt.StartState()) return true;
  if (mOnStack &lt; nt.OnStack()) return true;
  if (mEndState &lt; nt.EndState()) return true;
  return false;    
}
</code></pre>
