title: C++ misuse of template or problems of compilers string literal comparison with template
body: <p>When I am reading "C++ Primer" (4th Edition) Chapter 16.1, there is a simple template demo:</p>
  
  <pre><code>// implement strcmp-like generic compare function
  // returns 0 if the values are equal, 1 if v1 is larger, -1 if v1 is smaller
  template &lt;typename T&gt;
  int compare(const T &amp;v1, const T &amp;v2)
  {
      if (v1 &lt; v2) return -1;
      if (v2 &lt; v1) return 1;
          return 0;
  }
  </code></pre>
  
  <p>the invocation in main function:</p>
  
  <pre><code>int main ()
  {
      // T is int;
      // compiler instantiates int compare(const int&amp;, const int&amp;)
      cout &lt;&lt; compare(1, 0) &lt;&lt; endl;
      // T is string;
      // compiler instantiates int compare(const string&amp;, const string&amp;)
      string s1 = "hi", s2 = "world";
      cout &lt;&lt; compare(s1, s2) &lt;&lt; endl;
      return 0;
  }
  </code></pre>
  
  <p>I made several modifications over this piece of code:</p>
  
  <pre><code>//----------------------------test.cpp start----------------
  #include &lt;iostream&gt;
  #include &lt;string&gt;
  
  using namespace std;
  
  template&lt;class T&gt;
  int myCompare(const T &amp;v1, const T &amp;v2){
      cout &lt;&lt; v1 &lt;&lt; " " &lt;&lt; ((v1 &gt; v2) ? ("&gt;") : ((v1 &lt; v2) ? ("&lt;") : ("="))) &lt;&lt; " " &lt;&lt; v2 &lt;&lt; endl;
      return (v1 &gt; v2) ? (1) : ((v1 &lt; v2) ? (-1) : 0);
  };
  
  int main(void) {
      int iRes;
      cout &lt;&lt; "String 1 : " &lt;&lt; "A"&lt;&lt;endl;
      cout &lt;&lt; "String 2 : " &lt;&lt; "a"&lt;&lt;endl;
      iRes = myCompare("A", "a");
      cout &lt;&lt; "A " &lt;&lt; ((iRes == 1) ? ("&gt;") : ((iRes == (-1)) ? ("&lt;") : ("="))) &lt;&lt; " a" &lt;&lt; endl;
      return 0;
  };
  //----------------------------test.cpp end----------------
  </code></pre>
  
  <p>there is a problem when I compile and run it:</p>
  
  <p>under VS2008, it gives:</p>
  
  <pre><code>String 1 : A
  String 2 : a
  A &gt; a
  A &gt; a
  </code></pre>
  
  <p>under g++ (Debian 4.4.5-8) 4.4.5, it gives:</p>
  
  <pre><code>String 1 : A
  String 2 : a
  A &lt; a
  A &lt; a
  </code></pre>
  
  <p>the correct answer is <code>**A&lt;a**</code>.</p>
  
  <p>However, when I comment out the following:</p>
  
  <pre><code>cout &lt;&lt; "String 1 : " &lt;&lt; "A" &lt;&lt; endl;
  cout &lt;&lt; "String 2 : " &lt;&lt; "a" &lt;&lt; endl;
  </code></pre>
  
  <p>under VS2008, it gives:</p>
  
  <pre><code>String 1 : A
  String 2 : a
  A &lt; a
  A &lt; a
  </code></pre>
  
  <p>under g++ (Debian 4.4.5-8) 4.4.5, it gives:</p>
  
  <pre><code>String 1 : A
  String 2 : a
  A &gt; a
  A &gt; a
  </code></pre>
  
  <p>the compile command is as following:</p>
  
  <pre><code>g++ test.cpp -o test -Wall -O0
  </code></pre>
  
  <p>I want to know why this could happen? Is the problem (A?B:C) expression that I have used incorrectly? It seems that my code is correct. It has bothered me for days. Any help would be appreciated.</p>
  
  <hr>
  
  <p>Case Closed!</p>
  
  <p>I replaced the myCompare() invocation by the following:</p>
  
  <pre><code>iRes=myCompare(static_cast&lt;string&gt;("A"), static_cast&lt;string&gt;("a"));
  </code></pre>
  
  <p>It works. No matter how I change the context, it always gives the right answer. I should have been aware that I am comparing two <code>const char*</code>, I give it a try just to be sure about it.</p>
  
  <p>The lesson that I learned here is that this template could be instantiated into two functions:</p>
  
  <pre><code>int compare(const char* &amp;v1, const char* &amp;v2);     // two pointers
  int compare(const string &amp;v1, const string &amp;v2);   // two objects
  </code></pre>
  
  <p>Thanks for all the help that you guys offered. Really appreciated! Have a good day!</p>
  
  <hr>
  
  <p>Additional info.</p>
  
  <p>I added a simple express in the myCompare function:</p>
  
  <pre><code>cout&lt;&lt;"the type is : "&lt;&lt;typeid(T).name() &lt;&lt;endl;
  </code></pre>
  
  <p>this gives clear type information about what kind of type that T has been instantiated.
  the whole code is as following:</p>
  
  <pre><code>//----------------------------test.cpp start----------------
  #include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;typeinfo&gt;
  
  using namespace std;
  
  template&lt;class T&gt;
  int myCompare(const T &amp;v1, const T &amp;v2){
      cout&lt;&lt;"the type is : "&lt;&lt;typeid(T).name() &lt;&lt;endl;
      cout&lt;&lt;v1&lt;&lt;" "&lt;&lt;((v1&gt;v2)?("&gt;"):((v1&lt;v2)?("&lt;"):("=")))&lt;&lt;" "&lt;&lt;v2&lt;&lt;endl;
      return (v1&gt;v2)?(1):((v1&lt;v2)?(-1):0);
  };
  
  int main(void){
      int iRes;
      iRes=myCompare(1234, 3);
      iRes=myCompare("test","poor");
      iRes=myCompare(static_cast&lt;string&gt;("test"),static_cast&lt;string&gt;("poor"));
      iRes=myCompare(21.23,4.0);
      return 0;
  };
  
  //----------------------------test.cpp end----------------
  </code></pre>
  
  <p>this results of this program is:</p>
  
  <pre><code>the type is : i
  1234 &gt; 3
  the type is : A5_c
  test &gt; poor
  the type is : Ss
  test &gt; poor
  the type is : d
  21.23 &gt; 4
  </code></pre>
  
  <p>Notice that:</p>
  
  <pre><code>1, #include &lt;typeinfo&gt; should be included.
  2, the second comparison is incorrect, it simply compares the addresses of the constant char array rather than string stored in the constant char array.
  </code></pre>
  
  <p>Hope this would help someone like me who is struggling with templates.</p>