0

The following code works for the case of "==" (thanks to the solution provided by πάντα ῥεῖ) when comparing a string to a number. What about ">", ">=", "!=", "<", "<=" etc? Is it possible to avoid writing the functions for each of the operators by writing a function template? Typical function template is for same operation on different types, but we have different operations of the same type.

#include <unordered_map>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <iostream>

using namespace std;


bool operator==(const std::string& s, int i) {
    int n = atoi(s.c_str());
    return (n == i);
}

int main(int argc, char *argv[])
{
    string t("1234");
    printf("value is %s\n", t.c_str());
    if (t == atoi(argv[1])) {
        printf("yes\n");
    } else {
        printf("no\n");
    }
}

Thanks.

Community
  • 1
  • 1
packetie
  • 4,839
  • 8
  • 37
  • 72
  • 3
    Why are you converting `argv[1]` to number. Just compare it as a string. – Cheers and hth. - Alf May 17 '15 at 01:25
  • 3
    Anyway, since you are asking about `<`, for those who would like to jump on the chance to answer an obviously construed question it would ideally be beneficial to know whether you want lexicographic or numerical comparison? Please do be clear on that. – Cheers and hth. - Alf May 17 '15 at 01:27
  • I'd suggest just using itoa or to_string and/or atoi. It would definitely beat reinventing string conversion, which is going to be a part of this in some form or another. –  May 17 '15 at 01:58
  • Seems you totally misinterpreted _my solution_, based on a biased concept you have, about handling a numeric input given as string from `argv[1]`. – πάντα ῥεῖ May 17 '15 at 02:33

2 Answers2

2

"What about >, >=, !=, <, <=, etc? Is it possible to avoid writing the functions for each of the operators by writing a function template?"

This sounds like a XY problem.
Overloading all the possible comparison operators for std::string is the wrong way to solve this.

If you want to apply numeric comparison operations with a number given as a string, you simply convert the string once to a number, and apply comparisons to the converted value, and not overwrite every possible comparison operation with a std::string:

try {
    int i = stoi(argv[1]); // <<< convert once!
    if (i == 1234) { // Use numeric comparison operators ...
    // ... in any way you like:
    // if (i <= 1234) {
    // if (i >= 1234) {
    // if (i < 1234) {
    // if (i != 1234) {
    // ....
        printf("yes\n");
    } else {
        printf("no\n");
    }
}
catch(const std::exception& ex) {
   // conversion to number failed
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • I need it so that when other users write code without even knowing the type of the variable. They can do comparison with string, with numbers at will. Andrzej's solution is what I was looking for. Thanks @πάντα ῥεῖ anyway. – packetie May 17 '15 at 04:01
2

I assume that you are interested in knowing how can you provide operators relating a custom type to e.g. int without overloading all operators. One way to achieve that is to provide an implicit conversion to a type to which you want to relate your custom type (in this case int). See the example below.

#include <iostream>
using namespace std;

class Foo
{
 public:
  Foo(int val): _val(val)
  {}

  operator int()
  {
    return _val;
  }

 private:
  int _val;
};


int main()
{
  Foo foo(2);

  cout << foo << endl;
  cout << (foo == 2) << endl;
  cout << (foo > 3) << endl;
}

which would produce:

2
1
0

Now, if you are only interested in the string-to-int situation, I would simply suggest using the Boost lexical_cast as shown in this example from http://www.boost.org/doc/libs/1_58_0/doc/html/boost_lexical_cast/examples.html:

#include <boost/lexical_cast.hpp>
#include <vector>

int main(int /*argc*/, char * argv[])
{
    using boost::lexical_cast;
    using boost::bad_lexical_cast;

    std::vector<short> args;

    while (*++argv)
    {
        try
        {
            args.push_back(lexical_cast<short>(*argv));
        }
        catch(const bad_lexical_cast &)
        {
            args.push_back(0);
        }
    }
}

Or, if you're using C++11, just follow this: std::lexical_cast - is there such a thing?

Community
  • 1
  • 1
Andrzej Pronobis
  • 33,828
  • 17
  • 76
  • 92
  • The operator overloading issue was already discussed and clarified in the [prequel discussion](http://stackoverflow.com/questions/30281828/skipping-adding-constructors-when-inheriting-from-stdstring-class). I don't see how this concretly answers the OP's question. – πάντα ῥεῖ May 17 '15 at 02:37
  • The answer is suggesting a conversion instead of overloading operators for a custom type (or string for that matter). – Andrzej Pronobis May 17 '15 at 02:42
  • Well, you might need to read where the question came from. It's about numerical conversion finally, yes. – πάντα ῥεῖ May 17 '15 at 02:46
  • That's exactly what I needed. I created a derived class from string and added this method `operator int()` and now all integer comparison operators works naturally! Thanks a lot. – packetie May 17 '15 at 03:58