C++ string() comparison with a c-string. WHY DOES THIS WORK?

430 views Asked by At

So this code is for a command input to be entered in any random order and it will return the value that comes after your input. Amt_Range is a digit checking function.

Why does this work. It should be able to due to the pointer comparison.??

More importantly what does the string() do. By my limited understanding the comparison should not work because a c style string is in the form '-' 't'. Thanks in advance!!

int main(int argc, const char *argv[]) {

string dummy;
int tests = 0, quizzes = 0, assignments = 0, labs = 0, fin = 0;
int testweight = 0, quizweight = 0, assignweight = 0, labweight = 0, finweight = 0;
int counter = 1;

    if (argv[counter] == string("-t")) {
        dummy = argv[counter + 1];
        tests = Amt_Range(dummy, "tests");
        counter+=2;

    } else if (argv[counter] == string("-q")) {
        dummy = argv[counter + 1];
        quizzes = Amt_Range(dummy, "quizzes");
        counter+=2;


    } else if (argv[counter] == string("-a")) {
        dummy = argv[counter + 1];
        assignments = Amt_Range(dummy, "assignments");
        counter+=2;


    } else if (argv[counter] == string("-l")) {
        dummy = argv[counter + 1];
        labs = Amt_Range(dummy, "labs");
        counter+=2;


    } else if (argv[counter] == string("-f")) {
        dummy = argv[counter + 1];
        fin = Amt_Range(dummy, "whether there is a final");
        counter+=2;

    } else {
    cout << "wrong input NOW START OVER" << endl;
    exit(EXIT_FAILURE);

    }
}
2

There are 2 answers

13
sehe On BEST ANSWER

The operator==() overload that kicks in is a free function in the std namespace.

namespace std { 
     bool operator==(std::string const&, std::string const&);
}

It takes the first argument by const& which means that a temporary is welcome.

A temporary happens to be creatable using the implicit conversion constructor std::string(char const*). So, the overload applies.

UPDATE As uncovered in the comments, the standard actually declares

      bool operator==(const char*, std::string const&);

as an optimization in ยง21.4.8.2 operator==. However, the implicit conversion on the LHS is good to know about because it's a key ingredient in the language design with respect to operator overload (resolution)


Now, the reason why the overload bool std::operator==(std::string const&, std::string const&) is even found during overload resolution is slightly subtle. This mechanism is known as Argument Dependent Lookup.

In this case, ADL works because the second argument is already a std::string, which has a type declared in the std namespace. Therefore, this namespace is searched for candidate operator== overloads


DISCLAIMER:

I've simplified the above. In reality the code in the standard library is much more generic still, and probably looks more like

namespace std { 
     template <typename Char, typename CharTraits, typename Alloc>
     bool operator==(std::basic_string<Char, CharTraits, Alloc> const&, std::basic_string<Char, CharTraits, Alloc>  const&) {
          // implementation...
     }
}
6
Deduplicator On

Quote from the standard (C++14):

21.3 String classes [string.classes]

template<class charT, class traits, class Allocator>
bool operator==(const basic_string<charT,traits,Allocator>& lhs,
    const basic_string<charT,traits,Allocator>& rhs) noexcept;
template<class charT, class traits, class Allocator>
bool operator==(const charT* lhs, const basic_string<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs);

[... same for != < > <= >=]

Or look in this section:

21.4.8.2 operator== [string::operator==]

So there is an exact match, which is found in namespace std (would use ADL (argument-dependent lookup, counting the arguments namespaces as associated namespaces and searching them too) if there was no using-directive in scope).

BTW: I'm a bit disappointed that two std::basic_strings differing only in allocator-type cannot be compared (template-arguments must match exactly)...
A quick demo on coliru: http://coliru.stacked-crooked.com/a/01788a718178c6d2