title: Templated stream operators, unresolved externals
body: <p>In a previous project I encountered similar errors, so I decided to start fresh from a new approach and am still getting the same issues. I have a key-value pair template class, and everything is working except for the stream operators. I have templates for <code>&lt;&lt;</code> accepting either a <code>kvp_node&lt;key, elem&gt; &amp;kvp</code> or <code>kvp_node&lt;key, elem&gt; *kvp</code>. I am able to create <code>kvp_node</code> objects and use their member functions with no issues. But if I try to do something like:</p>
  
  <pre><code>kvp_node&lt;char, int&gt; test('A', 10);
  std::cout &lt;&lt; test;
  </code></pre>
  
  <p>It gives me the unresolved external operator error.
  I feel as if I have defined my stream operators correctly. If I try to just do:</p>
  
  <pre><code>kvp_node&lt;char, int&gt; name('J', 12);
  std::cout &lt;&lt; name.elm_();
  </code></pre>
  
  <p>it works without error, and that is why this is confusing since all the ostream operator does is </p>
  
  <p><code>os &lt;&lt; (kvp_node&lt;key, elem&gt; test(key, elem)).elm_()</code></p>
  
  <p>This is my header file:</p>
  
  <pre><code>#ifndef DICT_H_
  #define DICT_H_
  #include&lt;iostream&gt;
  #include&lt;fstream&gt;
  
  
  //Stores Key Value pairs in a linked node can be used 
  //to implement various KV based ADTs
  //kvp_nodes can be compared using normal comparator
  //operations. These operations will use the comparators
  //for the key class type, so if the key class is a user
  //defined type, they must define the comparators for the
  //class
  template&lt;typename key, typename elem&gt;
  class kvp_node {
      bool setinel;
      key k_val;
      elem e_val;
      kvp_node&lt;key, elem&gt; *next;
      kvp_node&lt;key, elem&gt; *prev;
  public:
      //default constructor
      kvp_node();
      //use this constructor
      kvp_node(key k, elem e, bool set = false);
      //destructor
      ~kvp_node();
      //copy constructor
      kvp_node(const kvp_node&lt;key, elem&gt; &amp;kvp);
      //assignment constructor
      void operator=(const kvp_node&lt;key, elem&gt; &amp;kvp_);
  
      //returns keyvalue
      key key_();
      //returns element
      elem elm_();
  
      //sets key value
      void set_key(key k);
      //sets element value
      void set_elm(elem e);
  
      //comparators, all will use the default comparators for the key type
      bool operator==(kvp_node&lt;key, elem&gt; &amp;kvp);
      bool operator&gt;=(kvp_node&lt;key, elem&gt; &amp;kvp);
      bool operator&lt;=(kvp_node&lt;key, elem&gt; &amp;kvp);
      bool operator&gt;(kvp_node&lt;key, elem&gt; &amp;kvp);
      bool operator&lt;(kvp_node&lt;key, elem&gt; &amp;kvp);
  
      //returns next node
      kvp_node&lt;key, elem&gt; *gnext();
      //returns previous node
      kvp_node&lt;key, elem&gt; *gprev();
  
      //node linking functions
      //sets the next node
      void set_next(kvp_node&lt;key, elem&gt; *kvp);
      //sets the previous node
      void set_prev(kvp_node&lt;key, elem&gt; *kvp);
      //links node a forward to b and b backward to a
      void link_nodes(kvp_node&lt;key, elem&gt; *A, kvp_node&lt;key, elem&gt; *B);
  
      //setinel functions
      //makes setinel
      void set_set();
      //returns setinel value
      bool set();
  
      //standard io stream operators
      //ostream &lt;&lt;
      friend std::ostream&amp; operator&lt;&lt;(std::ostream &amp;os, kvp_node&lt;key, elem&gt; &amp;kvp);
      friend std::ostream&amp; operator&lt;&lt;(std::ostream &amp;os, kvp_node&lt;key, elem&gt; *kvp);
      //istream
      //add later
  
      //standard file stream operators
      //ofstream &lt;&lt;
      friend std::ofstream&amp; operator&lt;&lt;(std::ofstream &amp;fo, kvp_node&lt;key, elem&gt; &amp;kvp);
      friend std::ofstream&amp; operator&lt;&lt;(std::ofstream &amp;fo, kvp_node&lt;key, elem&gt; *kvp);
      //ifstream
      //add later
  };
  
  
  //constructors, destructors, assignment
  template&lt;typename key, typename elem&gt;
  kvp_node&lt;key, elem&gt;::kvp_node() {
  }
  
  template&lt;typename key, typename elem&gt;
  kvp_node&lt;key, elem&gt;::kvp_node(key k, elem e, bool set) {
      k_val = k;
      e_val = e;
      setinel = set;
  }
  
  template&lt;typename key, typename elem&gt;
  kvp_node&lt;key, elem&gt;::~kvp_node(){
  
  }
  
  template&lt;typename key, typename elem&gt;
  kvp_node&lt;key, elem&gt;::kvp_node(const kvp_node&lt;key, elem&gt; &amp;kvp) {
      k_val = kvp.key_();
      e_val = kvp.elm_();
      setinel = kvp.set();
  }
  
  template&lt;typename key, typename elem&gt;
  void kvp_node&lt;key, elem&gt;::operator=(const kvp_node&lt;key, elem&gt; &amp;kvp) {
      k_val = kvp.key_();
      e_val = kvp.elm_();
      setinel = kvp.set();
  }
  // ==================================
  //get object values
  template&lt;typename key, typename elem&gt;
  key kvp_node&lt;key, elem&gt;::key_() {
      return k_val;
  }
  
  template&lt;typename key, typename elem&gt;
  elem kvp_node&lt;key, elem&gt;::elm_() {
      return e_val;
  }
  
  template&lt;typename key, typename elem&gt;
  bool kvp_node&lt;key, elem&gt;::set() {
      return setinel;
  }
  // ==================================
  //set object values
  template&lt;typename key, typename elem&gt;
  void kvp_node&lt;key, elem&gt;::set_key(key k) {
      k_val = k;
  }
  
  template&lt;typename key, typename elem&gt;
  void kvp_node&lt;key, elem&gt;::set_elm(elem e) {
      e_val = e;
  }
  
  template&lt;typename key, typename elem&gt;
  void kvp_node&lt;key, elem&gt;::set_set() {
      setinel = true;
  }
  // =================================
  //get neighbor kv pair nodes
  template&lt;typename key, typename elem&gt;
  kvp_node&lt;key, elem&gt; *kvp_node&lt;key, elem&gt;::gnext() {
      return next;
  }
  
  template&lt;typename key, typename elem&gt;
  kvp_node&lt;key, elem&gt; *kvp_node&lt;key, elem&gt;::gprev() {
      return prev;
  }
  // =================================
  //set neighbor kv pair nodes
  template&lt;typename key, typename elem&gt;
  void kvp_node&lt;key, elem&gt;::set_next(kvp_node&lt;key, elem&gt; *kvp) {
      next = kvp;
  }
  
  template&lt;typename key, typename elem&gt;
  void kvp_node&lt;key, elem&gt;::set_prev(kvp_node&lt;key, elem&gt; *kvp) {
      prev = kvp;
  }
  
  template&lt;typename key, typename elem&gt;
  void kvp_node&lt;key, elem&gt;::link_nodes(kvp_node&lt;key, elem&gt; *A, kvp_node&lt;key, elem&gt; *B) {
      A-&gt;set_next(B);
      B-&gt;set_prev(A);
  }
  // ==================================
  //comparison operators
  template&lt;typename key, typename elem&gt;
  bool kvp_node&lt;key, elem&gt;::operator&lt;(kvp_node&lt;key, elem&gt; &amp;kvp) {
      return (k_val &lt; kvp.key_()) ? (true) : (false);
  }
  
  template&lt;typename key, typename elem&gt;
  bool kvp_node&lt;key, elem&gt;::operator&gt;(kvp_node&lt;key, elem&gt; &amp;kvp) {
      return (k_val &gt; kvp.key_()) ? (true) : (false);
  }
  
  template&lt;typename key, typename elem&gt;
  bool kvp_node&lt;key, elem&gt;::operator&lt;=(kvp_node&lt;key, elem&gt; &amp;kvp) {
      return (k_val &lt;= kvp.key_()) ? (true) : (false);
  }
  
  template&lt;typename key, typename elem&gt;
  bool kvp_node&lt;key, elem&gt;::operator&gt;=(kvp_node&lt;key, elem&gt; &amp;kvp) {
      return (k_val &gt;= kvp.key_()) ? (true) : (false);
  }
  
  template&lt;typename key, typename elem&gt;
  bool kvp_node&lt;key, elem&gt;::operator==(kvp_node&lt;key, elem&gt; &amp;kvp) {
      return (k_val == kvp.key_()) ? (true) : (false);
  }
  // ==================================
  //stream operators
  
  template&lt;typename key, typename elem&gt;
  std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, kvp_node&lt;key, elem&gt; &amp;kvp) {
      os &lt;&lt; kvp.elm_();
      return os;
  }
  
  template&lt;typename key,typename elem&gt;
  std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, kvp_node&lt;key, elem&gt; *kvp) {
      os &lt;&lt; kvp-&gt;elm_();
      return os;
  }
  
  #endif
  </code></pre>
  
  <p>How is it that I can use all other class members but the stream operators don't work?</p>