3

I have a simple code that compares couple values. I'm using template function to reduce the amount of code, so i overloaded function twice(for different cases).

    //cmp.h
        template <class T>
        bool cmp(T x,T y)
        {
           if(x == y)
           { 
           return true;
           }else
           return false;
        }

        template <class T>
bool cmp(T *x,T *y)
{
   if(*x==*y)
   { return true;}else
   return false;
}


        //main.cpp  
        #include <iostream>
        #include <string>
        #include "cmp.h"
        using std::cout;
        using std::endl;
        using std::string;
        int main() {
             int aInt = 1, bInt = 2;
             double aDouble = 3.0, bDouble = 3.0;
             char aChars[5] = "haha", bChars[5] = "hahb";
             char taChars[6] = "trick", tbChars[6] = "trick";
             string aStr = "haha", bStr = "aha";
             int* aIntPtr = &aInt, *bIntPtr = &bInt;
              cout << cmp(aInt, bInt)<< endl;
             cout << cmp(aDouble, bDouble)<< endl;
              cout << cmp(aChars, bChars)<< endl;//i can't figure out why char prints out true here ???
             cout << cmp(taChars, tbChars)<< endl;
             cout << cmp(aStr, bStr)<< endl;
             cout << cmp(aIntPtr, bIntPtr)<< endl;
             cout << cmp(&aDouble, &bDouble) << endl;
             return 0;
        }  

My output is:
0
1
1
1
0
0
1
And i expected:
0
1
0
1
0
0
1

Why it shows that two strings are identical ? Why if i entirely change the word, lets say

char aChars[5] = "jack", bChars[5] = "hahb";  

then only it gives the right result. Isn't my second overloaded function should handle this right? (bool cmp(T *x,T *y))

casper
  • 259
  • 4
  • 18

2 Answers2

3

Why it shows that two strings are identical ?

Because

template <class T>
bool cmp(T *x,T *y)
{
   if(*x == *y)
   { 
   return true;
   }else
   return false;
}  

check only the first value pointed by x and y.

So when you check

 char aChars[5] = "haha", bChars[5] = "hahb";

 cout << cmp(aChars, bChars)<< endl;//

check that h is equal to h.

If you want check the equality between strings (and if you want avoid the use of the good-old std::strcmp()) you have to check all characters until the first zero.

But this is true for old style C-string; I don't think it's a good idea to develop a function that check equality between pointer for a generic type T.

-- EDIT --

Could u guide me please

To give an example... it's a lot of time that I don't think in plain C but something as follows should works

bool cmp (char const * p1, char const * p2)
 {
   for ( ; *p1 && *p1 == *p2 ; ++p1, ++p2 )
    ;

   return *p1 == *p2;
 }

Off Topic: you write code as

bool cmp(T *x,T *y)
{
   if(*x==*y)
   { return true;}else
   return false;
}

It's equivalent to

bool cmp(T *x,T *y)
 { return *x == *y; }

More generally speaking... if you have a code of type

if ( someTest )
   return true;
else
   return false;

and the function return a bool (or someTest is of type bool), you can write (and, IMHO, is more readable and elegant) simply write

return someTest;
max66
  • 65,235
  • 10
  • 71
  • 111
  • to fix it, should i add a loop to go through each character? – casper Jun 06 '19 at 09:41
  • @casper - exactly; until one pointer (or the other, or both) point to zero. – max66 Jun 06 '19 at 09:43
  • @casper ...but then it will fail to compare non string arrays. Maybe add an overload for arrays, see eg here for some hints: https://stackoverflow.com/a/18078435/4117728 – 463035818_is_not_an_ai Jun 06 '19 at 09:49
  • i did tried to fix it, i edited that code wiht my new function, but still same issue. Could u guide me please @max66 – casper Jun 06 '19 at 10:23
  • @formerlyknownas_463035818 – casper Jun 06 '19 at 10:23
  • 1
    @casper please dont do that! Do not modify the code in your question after you got an answer! Now the question and the answer are useless and someone not knowing the original can only get confused by readin this Q&A. Instead you can open a new question – 463035818_is_not_an_ai Jun 06 '19 at 10:24
  • @casper - answer improved to give a possible solution (no more template, as you can see). – max66 Jun 06 '19 at 11:36
1

Why it shows that two strings are identical ?

Array decays to pointer, so char taChars[6] will use overload template <class T> bool cmp(T *x,T *y) and so compare only first element (which are equal in your case).

In C++17, you might do:

template <typename T>
bool cmp(const T& lhs, const T& rhs)
{
    if constexpr (std::is_pointer<T>::value) {
        return *lhs == *rhs;
    } else if constexpr (std::is_array<T>::value) {
        return std::equal(std::begin(lhs), std::end(lhs), std::begin(rhs), std::end(rhs));
    } else {
        return lhs == rhs;
    }
}

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302