title: template function overloading ambiguity
body: <p>A beginner's question here, so I have the following code</p>
  <p><code>foo.h</code></p>
  <pre class="lang-cpp prettyprint-override"><code>enum class Fruit : uint16_t {
      Apple  = 8019U,
      Orange = 8020U,
      Banana = 8021U,
      Cactus = 8022U
  };
  
  class Foo {
    public:
      template&lt;typename T&gt; void SetValue(unsigned int location, const T&amp; value);
      template&lt;typename T&gt; void SetValue(unsigned int location, const T* value_ptr);
      template&lt;typename T&gt; void SetValue(Fruit fruit, const T&amp; value);
      template&lt;typename T&gt; void SetValue(Fruit fruit, const T* value_ptr);
  }
  </code></pre>
  <p><code>foo.cpp</code></p>
  <pre class="lang-cpp prettyprint-override"><code>template&lt;typename T&gt;
  void Foo::SetValue(unsigned int location, const T&amp; value) {
      std::cout &lt;&lt; value &lt;&lt; std::endl;
  }
  
  template&lt;typename T&gt;
  void Foo::SetValue(unsigned int location, const T* value_ptr) {
      std::cout &lt;&lt; (*value_ptr) &lt;&lt; std::endl;
  }
  
  template&lt;typename T&gt;
  void Foo::SetValue(Fruit fruit, const T&amp; value) {
      SetValue&lt;T&gt;(static_cast&lt;unsigned int&gt;(fruit), value);
  }
  
  template&lt;typename T&gt;
  void Foo::SetValue(Fruit fruit, const T* value_ptr) {
      SetValue&lt;T&gt;(static_cast&lt;unsigned int&gt;(fruit), value_ptr);
  }
  
  #define INSTANTIATE_TEMPLATE(T) \
      template void Foo::SetValue&lt;T&gt;(unsigned int location, const T&amp; value); \
      template void Foo::SetValue&lt;T&gt;(unsigned int location, const T* value_ptr); \
      template void Foo::SetValue&lt;T&gt;(Fruit fruit, const T&amp; value); \
      template void Foo::SetValue&lt;T&gt;(Fruit fruit, const T* value_ptr);
  
  INSTANTIATE_TEMPLATE(int)
  INSTANTIATE_TEMPLATE(uint)
  INSTANTIATE_TEMPLATE(bool)
  INSTANTIATE_TEMPLATE(float)
  INSTANTIATE_TEMPLATE(vec2)
  INSTANTIATE_TEMPLATE(vec3)
  INSTANTIATE_TEMPLATE(vec4)
  INSTANTIATE_TEMPLATE(mat2)
  INSTANTIATE_TEMPLATE(mat3)
  INSTANTIATE_TEMPLATE(mat4)
  ...
  
  #undef INSTANTIATE_TEMPLATE
  </code></pre>
  <p><code>main.cpp</code></p>
  <pre class="lang-cpp prettyprint-override"><code>int main() {
      Foo foo;
  
      float bar[7] { 0.0f, 0.15f, 0.3f, 0.45f, 0.6f, 0.75f, 0.9f };
      float baz = 12.5f;
  
      foo.SetValue(Fruit::Orange, 1.05);  // calling SetValue&lt;double&gt;(Fruit fruit, const double&amp; value)
  
      foo.SetValue(Fruit::Apple, bar + 3);  // calling SetValue&lt;float*&gt;(Fruit fruit, float *const&amp; value)
      foo.SetValue(Fruit::Cactus, &amp;baz);    // calling SetValue&lt;float*&gt;(Fruit fruit, float *const&amp; value)
  }
  </code></pre>
  <p>In the last 2 calls, while I really intended to call<br />
  <code>SetValue&lt;float&gt;(Fruit fruit, const float* value_ptr)</code></p>
  <p>What actually gets called are<br />
  <code>SetValue&lt;float*&gt;(Fruit fruit, float *const&amp; value)</code></p>
  <p>I'm aware that this is ambiguous because VS Intellisense was not able to color highlight <code>SetValue&lt;T&gt;</code> in the overridden function body, so I tried to write <code>foo.SetValue&lt;float&gt;(Fruit::Cactus, &amp;baz)</code> instead, now the compiler interprets <code>T</code> as <code>float</code> rather than <code>float*</code>, but I wonder if this is a horrible design...... Is there a better approach that doesn't require me to explicitly specify the type of <code>T</code>? How can I eliminate the ambiguity completely?</p>