title: Specializations only for C++ template function with enum non-type template parameter
body: <p>This question is related to <a href="https://stackoverflow.com/questions/2155491/hide-function-template-declare-specializations">this one</a> except that rather than dealing with typename template parameters, I am trying to use an enum non-type template parameter.</p>
  
  <p>Is it possible to have a templated (class member function) with only specializations, no general (working) definition in the case of non-type template parameter?</p>
  
  <ol>
  <li><p>I was able to get one version working, by declaration in the class body and providing specializations only, but any misuse calling with a non-defined template parameter doesn't produce an error until linking. What's worse is the missing symbol cryptically refers to the enum's integral value and not its name, so it would be confusing to other developers.</p></li>
  <li><p>I was able to get the <code>BOOST_STATIC_ASSERT</code> technique from the referenced question to work for typename template parameter only.</p></li>
  </ol>
  
  <p>This code demonstrates the idea.  I don't want the <code>CAT</code>-version call to compile:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;boost/static_assert.hpp&gt;
  
  // CLASS HEADER FILE:
  struct foo_class
  {
      enum AllowedTypes { DOG, CAT };
  
      template &lt;AllowedTypes type&gt;
      void add_one_third( double bar ) const
      {
          BOOST_STATIC_ASSERT_MSG(sizeof(type)==0, "enum type not supported.");
      }
  };
  
  // CLASS SOURCE FILE
  template&lt;&gt;
  void foo_class::add_one_third&lt;foo_class::DOG&gt;( double bar ) const
  {
      std::cout &lt;&lt; "DOG specialization: " &lt;&lt; bar + 1./3. &lt;&lt; std::endl;
  }
  
  
  // USER SOURCE FILE
  int main()
  {
      std::cout &lt;&lt; "Template Specialization!\n\n";
  
      foo_class a;
      a.add_one_third&lt;foo_class::DOG&gt;(3.0); // should succeed
      // Compilation fails with or without the following line:
      a.add_one_third&lt;foo_class::CAT&gt;(3.0); // should fail at compile-time
  
      return 0;
  }
  </code></pre>
  
  <p><strong>Background:</strong>
  I have a class member function that takes an enum "ArgType" and a name.</p>
  
  <pre><code>void declareKernelArgument( ArgType type, std::string name );
  </code></pre>
  
  <p>The definition has turned into an <code>if..else..if..else</code> list for the half-dozen or so allowed ArgType cases. I also have to have final case that throws an exception for an not-allowed ArgType. I'm thinking it would be cleaner to move ArgType to a template parameter, and provide a specialization for each allowed ArgType.  Misuse would be caught at compile-time.</p>