title: Implicit construction and templated class
body: <p>The question is simple, how you use implicit construction/conversion for templated class in C++14.</p>
  <p>Comment on the code below,
  <code>A</code> is what is expected, automatic construction/conversion of <code>const char*</code> to <code>A</code>.</p>
  <p>B is a templated class, I do not have the expected behavior of A and to get a &quot;similar&quot; behavior I need to specify the type against which I'll, in this case test compare equal (note the explicit <code>const T*</code> and not <code>const B&lt;T&gt;&amp;</code>). This is problematic because I would expect an automatic conversion from <code>const T*</code> to <code>B&lt;T&gt;</code> as specified in <code>B</code>'s constructor.</p>
  <p><code>C</code> is a templated class and exposes the behavior of <code>A</code>. It is a better solution to the problem than <code>B</code> is. The problem, it requires the use of a template trick, see below. The goal would be to ditch this trick. The trick solves the problem, can we make it work without it ?</p>
  <p>Note: the code below is compiling on &quot;recent&quot; versions of g++/clang++/msvc and icc without error.</p>
  <p>Code below accessible here: <a href="https://godbolt.org/z/W9x5Kcqrn" rel="nofollow noreferrer">https://godbolt.org/z/W9x5Kcqrn</a></p>
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;cassert&gt;
  #include &lt;iostream&gt;
  
  struct A {
      A(const char *aze) { std::cout &lt;&lt; &quot;A ctor\n&quot;; }
  };
  
  template &lt;typename T&gt;
  struct B {
      B(const T *aze) { std::cout &lt;&lt; &quot;B&lt;T&gt; ctor\n&quot;; }
  };
  
  template &lt;typename T&gt;
  struct C {
      C(const T *aze) { std::cout &lt;&lt; &quot;C&lt;T&gt; ctor\n&quot;; }
  };
  
  ////////////////////////////////
  
  bool operator==(const A &amp;, const A &amp;) {
      std::cout &lt;&lt; &quot;A==A\n&quot;;
      return true;
  }
  
  ////
  
  template &lt;typename T&gt;
  bool operator==(const B&lt;T&gt; &amp;, const T *) { // I dont want const T* here, I already have a constructor that can do it for me
      std::cout &lt;&lt; &quot;B&lt;T&gt;==T*\n&quot;;
      return true;
  }
  
  template &lt;typename T&gt;
  bool operator==(const T *, const B&lt;T&gt; &amp;) { // I dont want const T* here, I already have a constructor that can do it for me
      std::cout &lt;&lt; &quot;T*==B&lt;T&gt;\n&quot;;
      return true;
  }
  
  ////
  
  // I would like to ditch this TypeIdentity trickery
  
  template &lt;class T&gt;
  struct TypeIdentity {
      using type = T;
  };
  
  template &lt;class T&gt;
  using TypeIdentity_t = typename TypeIdentity&lt;T&gt;::type;
  
  template &lt;typename T&gt;
  bool operator==(const C&lt;T&gt; &amp;, const TypeIdentity_t&lt;C&lt;T&gt;&gt; &amp;) {
      std::cout &lt;&lt; &quot;C&lt;T&gt;==C&lt;tT&gt;\n&quot;;
      return true;
  }
  
  template &lt;typename T&gt;
  bool operator==(const TypeIdentity_t&lt;C&lt;T&gt;&gt; &amp;, const C&lt;T&gt; &amp;) {
      std::cout &lt;&lt; &quot;C&lt;tT&gt;==C&lt;T&gt;\n&quot;;
      return true;
  }
  
  template &lt;typename T&gt;
  bool operator==(const C&lt;T&gt; &amp;, const C&lt;T&gt; &amp;) {
      std::cout &lt;&lt; &quot;C&lt;T&gt;==C&lt;T&gt;\n&quot;;
      return true;
  }
  
  ////////////////////////////////
  
  int main() {
      // Works as expected, conversion of &quot;xrb&quot; to A and then operator==(const A &amp;,
      // const A &amp;) called
      // Prints: A ctor  A ctor  A==A
      assert(A{&quot;aze&quot;} == &quot;xrb&quot;);
  
      // Works as expected, operator==(const B&lt;T&gt; &amp;, const T *) called
      // Prints: B&lt;T&gt; ctor  B&lt;T&gt;==T*
      assert(B&lt;char&gt;{&quot;aze&quot;} == &quot;xrb&quot;);
      // Works as expected, operator==(const T *, const B&lt;T&gt; &amp;) called
      // Prints: B&lt;T&gt; ctor  T*==B&lt;T&gt;
      assert(&quot;aze&quot; == B&lt;char&gt;{&quot;xrb&quot;});
  
      // Work as expected with TypeIdentity_t, does not compile without it
      assert(C&lt;char&gt;{&quot;aze&quot;} == &quot;xrb&quot;);
      assert(&quot;xrb&quot; == C&lt;char&gt;{&quot;aze&quot;});
      assert(C&lt;const char&gt;{&quot;aze&quot;} == &quot;xrb&quot;);
  
      // Works as expected, operator==(const C&lt;T&gt; &amp;, const C&lt;T&gt; &amp;) called
      // Prints: C&lt;T&gt; ctor  C&lt;T&gt; ctor  C&lt;T&gt;==C&lt;T&gt;
      assert(C&lt;char&gt;{&quot;aze&quot;} == C&lt;char&gt;{&quot;xrb&quot;});
  }
  
  </code></pre>
  <p>Looking forward to your answers,
  Thanks</p>