title: C++ template function call seems to prefer the less specialized one
body: <p>I'm trying to simplify some of my earlier JSON serialization by using C++ templates to somewhat reduce boilerplate code. All went fine, until I wanted to serialize types such as lists, since these are templates themselves as well and seem to require partial template specialization, which does not seem to exist for template functions.</p>
  <p>Therefore, I applied a neat little trick I found over here:
  <a href="https://www.fluentcpp.com/2017/08/15/function-templates-partial-specialization-cpp/" rel="nofollow noreferrer">https://www.fluentcpp.com/2017/08/15/function-templates-partial-specialization-cpp/</a></p>
  <pre class="lang-cpp prettyprint-override"><code>namespace Support {
  // These are in header files
  template &lt;typename T&gt;
  struct convertType{};
  
  // Specialised template that serialises a list by iterating over its members
  template &lt;typename T&gt;
  QJsonValue toJsonValue(const QList&lt;T&gt; &amp;source, convertType&lt;QList&lt;T&gt;&gt;) {
      QJsonArray result;
      for (auto it = source.cbegin(); it != source.cend(); it++) {
          result.push_back(*it);
      }
      return result;
  }
  
  // &quot;Fallback&quot; template that generates an assertion
  template &lt;typename T&gt;
  QJsonValue toJsonValue(const T &amp;source, convertType&lt;T&gt;) {
      // This function should never be called.
      std::string msg = &quot;toJsonValue called with unimplemented type &quot;;
      msg += typeid (T).name();
      Q_ASSERT_X(false, &quot;toJsonValue&lt;T&gt;&quot;, msg.c_str()); // Always asserts. 
      return QJsonValue();
  }
  
  // Convenience function
  template&lt;typename T&gt;
  QJsonValue toJsonValue(const T &amp;source) {
      return toJsonValue&lt;T&gt;(source, convertType&lt;T&gt;{});
  }
  
  // This one is in the CPP file
  
  // Integer
  template &lt;&gt;
  QJsonValue toJsonValue(const int &amp;source, convertType&lt;int&gt;) {
      return QJsonValue(source);
  }
  
  } // NS Support
  </code></pre>
  <p>When I call this template with an integer as follows:</p>
  <pre class="lang-cpp prettyprint-override"><code>qDebug() &lt;&lt; Support::toJsonValue&lt;int&gt;(3713); // if not familiar with Qt, think as qDebug() being the same as std::cout.
  </code></pre>
  <p>This outputs &quot;QJsonValue(double, 3713)&quot;, as expected.</p>
  <p>However, when I try to pass a list as follows:</p>
  <pre class="lang-cpp prettyprint-override"><code>QList&lt;int&gt; foo = {1, 2, 3};
  qDebug() &lt;&lt; Support::toJsonValue&lt;QList&lt;int&gt;&gt;(foo);
  </code></pre>
  <p>The code will take, the in my eyes, least specialized function template, the one that generates an assertion. I have no idea why on earth this is happening, as I would expect that it would take the function template specialized for the <code>QList</code>.</p>
  <p>Does anyone have an idea why this is happening? Am I perhaps misusing templates?</p>