1

Tried to argument the std::string so that it supports method "bool operator==(int)". I got errors:

$ g++ -std=c++11 te2.cc
te2.cc: In function ‘int main(int, char**)’:
te2.cc:20:20: error: no matching function for call to ‘mstring::mstring(const char [4])’
te2.cc:20:20: note: candidates are:
te2.cc:10:7: note: mstring::mstring()
te2.cc:10:7: note:   candidate expects 0 arguments, 1 provided
te2.cc:10:7: note: mstring::mstring(const mstring&)
te2.cc:10:7: note:   no known conversion for argument 1 from ‘const char [4]’ to ‘const mstring&’
te2.cc:10:7: note: mstring::mstring(mstring&&)
te2.cc:10:7: note:   no known conversion for argument 1 from ‘const char [4]’ to ‘mstring&&’

Here is the simple source:

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

using namespace std;


class mstring : public string {
public:
    //mstring (char* p) : std::string(p) {};
    bool operator == (int x) {
        int n = atoi(this->c_str());
        return (n == x);
    }
};

int main(int argc, char *argv[])
{
    mstring t("123");
    if (t == atoi(argv[1])) {
        printf("yes\n");
    } else {
        printf("no\n");
    }
}

If I uncomment the constructor /mstring (char* p) : std::string(p) {};, then it compiles and runs fine.

The question is, if it possible to make it work without defining the constructors for mstring, just use the whatever the constructors of the base class (there is no new data member anyway)? Thanks.

3
  • 5
    Usually inheriting classes from the std namespace is a pretty bad idea. Commented May 16, 2015 at 23:45
  • You can define operator==(const std::string&, int) as a standalone, non-member function, if you are so inclined. In fact, you likely want it this way - you probably also want a symmetrical operator==(int, const std::string&), which can't be a member function anyhow. Commented May 16, 2015 at 23:46
  • 2
    You don't need to convert argv[1] to int. Compare it directly to a std::string. Commented May 16, 2015 at 23:49

2 Answers 2

5

What about providing a free standing operator function instead of inheriting from std::string (which makes that code more usable overall):

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

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

Or even more generic:

template<typename T>
bool operator==(const std::string& s, T t) {
    std::istringstream iss;
    iss << t;
    return (s == iss.str());
}

Classes from the std namespace aren't intended to be inherited, but just used in interfaces and function parameters. Inheriting from those classes makes your code less usable, since clients need to use your implementation instead of just using the std type.


Also note: For your particular use case it's not necessary to convert anything at all, unless you want to assert that argv[1] contains a number (where atoi() certainly isn't the best method to do so, look up stoi() instead). You can just compare the strings:

if (std::string("123") == argv[1]) {
    printf("yes\n");
} else {
    printf("no\n");
}
Sign up to request clarification or add additional context in comments.

1 Comment

That's the perfect solution. Seen it before but it didn't occur to me until I see your solution. Thanks.
2

you can explicitly inherit the constructors by adding

using string::string;

in your class

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.