I'm trying to compare libpqxx c_str values.
If I try to compare them directly, result1[0][0].c_str() == result2[0][0].c_str(), for example, they do not return true when they have the same string values. The only way to compare them properly is to use strcmp.
However, if I'm comparing a libpqxx c_str to a std::string with strcmp, the compiler complains that an argument of strcmp cannot be a std::string, yet most strangely of all to me: if I compare something like result1[0][0].c_str() == some_std_string, the comparison will return true if they possess the same value, false otherwise.
Why is this? Is this something particular to libpqxx? If not, is this standard behavior?
22 Answers
It happens because std::string is a class, while const char* (the type returned by c_str) is, well, a pointer type. Comparing pointers returns true if the pointers point to the same memory location. Classes, on the other hand, can define what equality means to them.
Since strings and const char* are fairly analogous, the string class defines a method of comparing string objects to const char* pointers. It also defines how to convert a char pointer into a string. However, this is essentially a one-way street, as it does not define how to create a const char* from a string using mere operators or implicit conversions. This is why you can't use strcmp on them.
Strcmp is a function from the C standard library. C has no classes and types cannot define basic behavior like C++ classes can. Therefore, C defines a bunch of function to deal with char pointers, and char pointers only.
This kind of inconsistency between char pointers and strings isn't limited to equality. For instance, std::string supports concatenation with the + operator: this means that string + string works, const char* + string works, string + const char* works, but const char* + const char* results in a compile-time error, because pointers don't define this kind of operation.
Just use c_str(), too!
if (strcmp(result1[0][0].c_str(), some_std_string.c_str()) == 0) { ... or use operator == of std::string
if (result1[0][0].c_str() == some_std_string) 5