title: How do you create a static template member function that performs actions on a template class?
body: <p>I'm trying to create a generic function that removes duplicates from an std::vector.  Since I don't want to create a function for each vector type, I want to make this a template function that can accept vectors of any type.  Here is what I have:</p>
  
  <pre><code>//foo.h
  
  Class Foo {
  
  template&lt;typename T&gt;
  static void RemoveVectorDuplicates(std::vector&lt;T&gt;&amp; vectorToUpdate);
  
  };
  
  //foo.cpp
  
  template&lt;typename T&gt;
  void Foo::RemoveVectorDuplicates(std::vector&lt;T&gt;&amp; vectorToUpdate) {
  for(typename T::iterator sourceIter = vectorToUpdate.begin(); (sourceIter != vectorToUpdate.end() - 1); sourceIter++) {
          for(typename T::iterator compareIter = (vectorToUpdate.begin() + 1); compareIter != vectorToUpdate.end(); compareIter++) {
              if(sourceIter == compareIter) {
                  vectorToUpdate.erase(compareIter);
              }
          }
      }
  }
  
  //SomeOtherClass.cpp
  
  #include "foo.h"
  
  ...
  
  void SomeOtherClass::SomeFunction(void) {
      std::vector&lt;int&gt; myVector;
  
      //fill vector with values
  
      Foo::RemoveVectorDuplicates(myVector);
  }
  </code></pre>
  
  <p>I keep getting a linker error, but it compiles fine.  Any ideas as to what I'm doing wrong?</p>
  
  <p>UPDATE: Based on the answer given by Iraimbilanja, I went and rewrote the code.  However, just in case someone wanted working code to do the RemoveDuplicates function, here it is:</p>
  
  <pre><code>//foo.h
  
  Class Foo {
  
      template&lt;typename T&gt;
      static void RemoveVectorDuplicates(T&amp; vectorToUpdate){
          for(typename T::iterator sourceIter = vectorToUpdate.begin(); sourceIter != vectorToUpdate.end(); sourceIter++) {
              for(typename T::iterator compareIter = (sourceIter + 1); compareIter != vectorToUpdate.end(); compareIter++) {
              if(*sourceIter == *compareIter) {
                  compareIter = vectorToUpdate.erase(compareIter);
              }
          }
      }
  };
  </code></pre>
  
  <p>Turns out that if I specify std::vector in the signature, the iterators don't work correctly. So I had to go with a more generic approach. Also, when erasing compareIter, the next iteration of the loop produces a pointer exception. The post decrement of compareIter on an erase takes care of that problem. I also fixed the bugs in the iterator compare and in the initialization of compareIter in the 2nd loop.</p>
  
  <p>UPDATE 2:</p>
  
  <p>I saw that this question got another up vote, so figured I'd update it with a better algorithm that uses some C++14 goodness. My previous one only worked if the type stored in the vector implemented operator== and it required a bunch of copies and unnecessary comparisons. And, in hindsight, there is no need to make it a member of a class. This new algorithm allows for a custom compare predicate, shrinks the compare space as duplicates are found and makes a significantly smaller number of copies. The name has been changed to <code>erase_duplicates</code> to better conform to STL algorithm naming conventions.</p>
  
  <pre><code>template&lt;typename T&gt;
  static void erase_duplicates(T&amp; containerToUpdate) 
  {
      erase_duplicates(containerToUpdate, nullptr);
  }
  
  template&lt;typename T&gt;
  static void erase_duplicates(T&amp; containerToUpdate, 
    std::function&lt;bool (typename T::value_type const&amp;, typename T::value_type const&amp;)&gt; pred) 
  {
      auto lastNonDuplicateIter = begin(containerToUpdate);
      auto firstDuplicateIter = end(containerToUpdate);
      while (lastNonDuplicateIter != firstDuplicateIter) {
          firstDuplicateIter = std::remove_if(lastNonDuplicateIter + 1, firstDuplicateIter, 
              [&amp;lastNonDuplicateIter, &amp;pred](auto const&amp; compareItem){
              if (pred != nullptr) {
                  return pred(*lastNonDuplicateIter, compareItem);
              }
              else {
                  return *lastNonDuplicateIter == compareItem;
              }
          });
          ++lastNonDuplicateIter;
      }
      containerToUpdate.erase(firstDuplicateIter, end(containerToUpdate));
  }
  </code></pre>