title: unable to match function definition to an existing declaration
body: <p>While attempting to provide an implimentation to <a href="https://stackoverflow.com/questions/8348459">this question</a>, I got stuck on an error.  I'm getting errors for 8 of my functions like this: </p>
  
  <blockquote>
    <p>f:\code\utilities\hypergraph\hypergraph\hypergraph.h(233): error C2244: 'hypergraph::add_edge' : unable to match function definition to an existing declaration<br>
             f:\code\utilities\hypergraph\hypergraph\hypergraph.h(68) : see declaration of 'hypergraph::add_edge'<br>
             definition<br>
             'hypergraph::node_iter hypergraph::add_edge(void)'<br>
             existing declarations<br>
             'std::set::node*,ptr_cmp::node,P>,A>::const_iterator hypergraph::add_edge(void)'  </p>
  </blockquote>
  
  <p>for this class:</p>
  
  <pre><code>template&lt;class T, class P&gt;
  struct ptr_cmp 
      : public std::binary_function&lt;T, T, bool&gt; {
      P p_;
      ptr_cmp(P p=P()) :p_(p) {}
      bool operator()(const T* l, const T* r) const
      { return p_(*l, *r);}
  };
  
  template&lt;class T, class P = std::less&lt;T&gt;, class A=std::allocator&lt;T&gt; &gt;
  class hypergraph {
      typedef A sub_allocator;
  public:
      class node;
      class edge;
      typedef std::set&lt;edge*, ptr_cmp&lt;edge, std::less&lt;edge&gt; &gt;, sub_allocator&gt; edgeset;
      typedef std::set&lt;node*, ptr_cmp&lt;node, P&gt;, sub_allocator&gt; nodeset;
      typedef typename std::set&lt;edge*, ptr_cmp&lt;edge, std::less&lt;edge&gt; &gt;, sub_allocator&gt;::const_iterator edgeiter;
      typedef typename std::set&lt;node*, ptr_cmp&lt;node, P&gt;, sub_allocator&gt;::const_iterator nodeiter;
  
      class node { /*SNIP*/};
      class edge { /*SNIP*/};
  
      hypergraph(P pred=P(), A alloc=A());
  
      nodeiter add_node(); /* beginning of 8 with the error */
      nodeiter add_node(const T&amp; rhs);
      nodeiter add_node(T&amp;&amp; rhs);
      nodeiter add_edge();
      nodeiter erase(nodeiter iter);
      nodeiter erase(node* iter);
      nodeiter erase(edgeiter iter);
      nodeiter erase(edge* iter);  /* end of 8 with the error */
  
      const nodeset&amp; nodes() const;
      const edgeset&amp; edges() const;
  
      A get_allocator() const;
  protected:
      hypergraph(const hypergraph&amp; rhs);
      hypergraph&amp; operator=(const hypergraph&amp; rhs);
      A a_;
      nodeset nodes_;
      edgeset edges_;
      unsigned int edgecount_;
  };
  </code></pre>
  
  <p>And this function definition: </p>
  
  <pre><code>template&lt;class T, class P, class A&gt;
  typename hypergraph&lt;T,P,A&gt;::node_iter hypergraph&lt;T,P,A&gt;::add_edge()
  {
      std::unique_ptr&lt;edge&gt; ptr = new edge(edgecount_++, sub_allocator(a_));
      std::pair&lt;edgeiter, bool&gt; r = edges_.insert(ptr);
      ptr.release();
      return r.first;
  }
  </code></pre>
  
  <p>I'm sure it's a stupid thing, but I can't figure out why MSVC10 can't match that prototype to that function.</p>
  
  <p>And I think this code has an issue with const-ness, caused by containers of pointers, but I'll address that in a separate question.</p>