tags:

views:

169

answers:

4

Why does the following not invoke the overloaded operator== (const String &, const String &)?

"cobble" == "stone"
+5  A: 

Because implicitly existing operator==(char*, char*) matches your usage of == better.

The operator == in code "cobble" == "stone" can be matched in different ways: operator==(char[], const String&), operator==(const String&, String), operator==(const String&, const std::string&) etc., provided that the conversion from the parameter type (char*) to the type of arguments (String*, etc.) exists. However the usual char* comparison matches the input best of all.

Vlad
surender
@Vlad: Conversion from a string literal to `char*` are deprecated and should not be used. You should use `const char*` instead.
sbi
The operator ==(char*, char*) is always implicitly provided by the compiler. This way you can compare pointers :-) It just compares the pointer values, not strings.
Vlad
sbi
@vlad can u answer my second question?
surender
Vlad
@sbi: I assumed OP means some custom class with string semantics.
Vlad
@Vlad: ...if these conversions are _implicit_.
sbi
@Vlad: So did I, until the OP wrote `string`. Now I'm not sure anymore.
sbi
@sbi: yes, indeed.
Vlad
i have written following codeif("cobol" == str)// str is object of my slef made class Stringi have written bool operator == ( char *str1, String as well but it showing error can u explain?
surender
@surender: It would be easier to answer if you asked that in a new question? Include the (relevant) code for your `String` class, the code showing the `if` statement that you are trying to do, and details about the error that you are receiving.
Matthew T. Staebler
@surender: which is the error message? Maybe you can expand your original answer and post your code there?
Vlad
+5  A: 

Because those are simple sequences of characters as in C but no instances of the string class.

Joey
+11  A: 

Because in C++, string literals are of the type const char[] (also called a zero-terminated string constant), not std::string, let alone String (whatever that is). The fact that string literals are character arrays we inherited from C.
There's a built-in operator== comparing two char* by comparing their addresses. Since arrays are implicitly convertible into pointers to their first elements (due, you guessed right, the C heritage), this operator steps in and what you compare are the addresses of these literals in memory.

Supposing your String class has an implicit conversion constructor from const char* (String::String(const char*)), you could convert one of the two to String. The other string would then be converted implicitly:

String("cobble") == "stone"

(Unless overloads of operator== taking a String and a const char* are provided for efficiency. If they are provided, they step in.)

sbi
"We inherited this from C" -- we did not. In C they were char[] without being const. Modifications were either undefined or otherwise dangerous, but were allowed syntactically because of historical reasons.
Windows programmer
sbi
"Correct me, please, if I'm wrong." -- You already were corrected and here is a repeat. 6.4.5 in the C standard, "the array elements have type char" without saying const.
Windows programmer
@Windows programmer: I haven't found anything in this thread quoting from 6.4.5., so I'm not sure where you think I already have been corrected regarding this. Anyway, I don't have a copy of the C standard to check this for myself, so I take your word for it that the above applies to string literals, and not to character arrays in general.
sbi
2 days prior to this comment, my first comment said "In C they were char[] without being const". I didn't bother looking it up that time. 6 hours prior to this comment I looked it up, found it in 6.4.5, and quoted from it. 6.4.5 is the section on string literals. sbi has been corrected twice.
Windows programmer
@Windows programmer: re "sbi has been corrected twice": I've had my share of corrections and I'm Ok with ti. If you feel great about correcting me twice, I'm fine with it. `<shrug>` I did say that my C is rusty. (And that was an understatement. I've always been a C++ programmer.) And I'm amazed at C's ignorance regarding `const` correctness. Anyway, my main point was that we inherited from C string literals being zero-terminated character arrays instead of `std::string` objects. Whether those arrays are `const` or not doesn't change that main point. Still, I will go and disambiguate my answer.
sbi
"so I'm not sure where you think I already have been corrected regarding this" -- so I showed you where, so you insult me, sheesh. "And I'm amazed at C's ignorance regarding const correctness" -- When C was invented it had string literals and it did something with them. The const keyword came along 10 years later. Someone figured it wouldn't be worth breaking millions of existing programs to force editing their declarations to become const correct.
Windows programmer
@Windows programmer: If you felt insulted, then be assured it wasn't my intention. I don't even have any idea _where and when_ I insulted you. I apologize nonetheless.
sbi
@sbi, "If you feel great about correcting me twice" -- This is quoted in order to show where and when, but don't worry, I accept your apology.
Windows programmer
A: 

"cobble" ist interpreted as a char*, and the compiler uses pointer comparison to compare char*. If you want to compare the contents of the strings, use

std::string("cobble") == std::string("stone")

instead, and the compiler will use operator== (const std::string &, const std::string &).

Danvil
Another answer says string literals are char[]. Is it char* or char[]? Does it matter?
AshleysBrain
It is char*, but as far as I know it does not matter.
Danvil
@Danvil Nope. @Ashleys: String literals have the type `const char[N]`, for some `N`. As you may know, arrays can decay to pointers, and in this case they can decay to `const char*`. There's also a *deprecated* conversion from `const char*` to `char*` which, if modified, leads to undefined behavior. String literals are certainly not `char*`'s.
GMan
@GMan: I agree with everything, except: Isn't the deprecated conversion from an revalue of `char[]` (aka a string literal) to `char*`?
sbi
With a parameter to a function, you always get a pointer even if you use array notation. `foo(char x[])` is exactly the same as `foo(char* x)`.
Danvil
@sbi: A string literal isn't `char[]`, it's `const char[]`
John Dibling
@sbi: Taking into account @John's correction, yes, I messed up. I meant a string literal can be converted to a `char*` (which is seen as a conversion to `const char*`, then to `char*`.) 4.2/2.
GMan
@John: ISTR that string literals are rvalues of `char[]` in the same sense that `42` isn't a `const int`, but an rvalue of `int`. Not that this would make much practical difference...
sbi
@GMan: I don't think you can implicitly convert `const char*` to `char*`. That exception was made explicitly for converting string literals (rvalues of `char[]`) to `char*`, because much of old C code didn't pay attention to const-correctness.
sbi
@sbi: Just looked it up in my copy of the standard. 2.13.4.1: "An ordinary string literal has type “array of n const char” and static storage duration (3.7), where n is the size of the string as defined below"
John Dibling
@sbi: integral literals are `int` however, just as you said. I think what may have thrown you off is that the standard treats `int` literals and string literals differently WRT const-ness.
John Dibling
@John: I stand corrected then, a string literal is indeed of the type `const char[]`. Thank you for looking this up. I just wish I would remember that...
sbi