Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

comparing a string variable to an explicit char* value in C++

I don’t understand why this code compiles and runs:

std::string s;
std::cin >> s;
// if (s == "done") {     // version 1
if ("done" == s) {        // version 2
    std::cout << "We're done here" << std::endl;
}

Version 1 works as I would expect. The compiler sees that s is a std::string, and uses the std::string definition of == to do the comparison.

However, when comparing a variable to an explicit value, I like to use the trick of putting the explicit value first in case one day I accidentally use = instead and do an assignment instead. Hence, version 2.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Now version 2 works on my compiler (llvm on MacOS) the same way as version 1, but I’m not sure why (or if it’s a reliable result). I would have though that the compiler sees "done" as a char* explicit constant and says, "hey, == makes no sense on char*" and give me a compilation error message. But my compiler doesn’t do that, it compiles without complaint and the code executes the same way as version 1.

What am I misunderstanding here?

>Solution :

The type of "done" is not char*. It is const char[5].

But in any case, it works because if you include <string>, which you must have to use std::string, then (before C++20) you include an overload for operator== of the form

template< class CharT, class Traits, class Alloc >
bool operator==( const std::basic_string<CharT,Traits,Alloc>& lhs,
                 const CharT* rhs );

and one of the form

template< class CharT, class Traits, class Alloc >
bool operator==( const CharT* lhs,
                 const std::basic_string<CharT,Traits,Alloc>& rhs );

See https://en.cppreference.com/w/cpp/string/basic_string/operator_cmp for reference.

std::string is just std::basic_string with CharT being char and Traits and Alloc being some defaults that don’t matter here.

So effectively one overload accepts a const std::string& as left-hand argument and const char* as right-hand argument, and the other accepts the reverse.

const char[N] can be deduced as const char* and it is implicitly convertible to the latter for every N, so the first overload is viable for s == "done" and the second for "done" == s.

The standard library is written with these overloads specifically so that your use will work. Your approach of using the "done" == s variant makes sense, because "done" = s would indeed be an error. operator= can only be overloaded with a class type on the left-hand side.

Since C++20, the overloads look a bit different. In particular it isn’t necessary to have both anymore. The compiler now automatically tries overloads matching the rewritten expression with reversed operands of == when doing overload resolution.


to an explicit value,

explicit constant

I am not sure what you mean here, but "explicit value" and "explicit constant" are not standard terminology. Probably you mean "(string) literal" instead.

and says, "hey, == makes no sense on char*"

It doesn’t work that way. As soon as either side of == is a class type, the compiler has to consider that == may be overloaded to match the expression.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading