title: C++ template function overload resolution bug
body: <pre><code>namespace Random
  {
      std::mt19937 engine_{ std::random_device{}() };
  
      template&lt;class T, class = std::enable_if_t&lt;std::is_integral&lt;T&gt;::value&gt;&gt;
      auto get(T from, T to)
      {
          return std::uniform_int_distribution&lt;T&gt;{from, to}(engine_);
      }
  
      template&lt;class T, class = std::enable_if_t&lt;std::is_same&lt;T, float&gt;::value&gt;&gt;
      auto get(T from, T to)
      {
      return std::uniform_real_distribution&lt;T&gt;{from, to}(engine_);
      }
  
  }
  int main()
  {
      std::cout.sync_with_stdio(false);
      std::cout.setf(std::ios_base::boolalpha);
      std::cout &lt;&lt; Random::get&lt;float&gt;(1.0f, 2.5f);//COMPILE TIME ERROR
      std::cin.get();
  }
  </code></pre>
  
  <p>compiler output: 
  18:4: error: redefinition of 'template T Random::get(T, T)'
  12:4: note: 'template T Random::get(T, T)' previously declared here
   In function 'int main()':
  28:44: error: no matching function for call to 'get(float, float)'
  28:44: note: candidate is:
  12:4: note: template T Random::get(T, T)
  12:4: note:   template argument deduction/substitution failed:</p>
  
  <p>This work fine:</p>
  
  <pre><code>#include &lt;type_traits&gt;
  #include &lt;random&gt;
  #include &lt;iostream&gt;
  
  namespace Random
  {
      std::mt19937 engine_{ std::random_device{}() };
  
      template&lt;class T, class = std::enable_if_t&lt;std::is_integral&lt;T&gt;::value&gt;&gt;
      auto get(T from, T to)
      {
          return std::uniform_int_distribution&lt;T&gt;{from, to}(engine_);
      }
  
      template&lt;class T, class = std::enable_if_t&lt;std::is_same&lt;T, float&gt;::value&gt;&gt;
      T get(T from, T to)
      {
      return std::uniform_real_distribution&lt;T&gt;{from, to}(engine_);
      }
  
  }
  int main()
  {
      std::cout.sync_with_stdio(false);
      std::cout.setf(std::ios_base::boolalpha);
      std::cout &lt;&lt; Random::get&lt;float&gt;(1.0f, 2.5f);//GOOD
      std::cin.get();
  }
  </code></pre>
  
  <p>and this:</p>
  
  <pre><code>#include &lt;type_traits&gt;
  #include &lt;random&gt;
  #include &lt;iostream&gt;
  
  namespace Random
  {
      std::mt19937 engine_{ std::random_device{}() };
  
      template&lt;class T, class = std::enable_if_t&lt;std::is_integral&lt;T&gt;::value&gt;&gt;
      auto get(T from, T to)
      {
          return std::uniform_int_distribution&lt;T&gt;{from, to}(engine_);
      }
  
      template&lt;class T&gt;
      std::enable_if_t&lt;std::is_same&lt;T, float&gt;::value, T&gt;
      get(T from, T to)
      {
          return std::uniform_real_distribution&lt;T&gt;{from, to}(engine_);
      }
  
  }
  int main()
  {
      std::cout.sync_with_stdio(false);
      std::cout.setf(std::ios_base::boolalpha);
      std::cout &lt;&lt; Random::get&lt;float&gt;(1.0f, 2.5f);//GOOD
      std::cin.get();
  }
  </code></pre>
  
  <p>Why compilers can't resolve this resolution in first example?</p>