Hi, I'm here again :D
Exercise 10.5: In the call to equal on rosters, what would happen if both rosters held C-style strings, rather than library strings?
And the answer given is:
Answer It's the same as std::string
But I think it is actually not the same as std::string
.
Code given:
int main() {
std::vector<const char *> roster1{"Mooophy", "pezy", "Queequeg"};
std::list<const char *> roster2{"Mooophy", "pezy", "Queequeg", "shbling", "evan617"};
std::cout << std::equal(roster1.cbegin(), roster1.cend(), roster2.cbegin());
}
As we know, c-style strings cannot be compared using ==
and <
and >
, 'casue these relational operators compare addresses in pointers rather than strings represented by char pointers.
And the "Mooophy", "pezy", "Queequeg"
in roster1
and "Mooophy", "pezy", "Queequeg"
in roster2
are all literals, and compiler optimized them to be stored in the same addresses. Thus yielded 1
.
std::cout << (void*)roster1[0] << std::endl;
std::cout << (void*)roster2.front() << std::endl;
On my pc, I got 0x401ec6
and 0x401ec6
.
Then look at this:
int main() {
const char a[3][2] = {"A", "B", "C"};
const char b[3][2] = {"A", "B", "C"};
std::vector<const char*> v1(std::begin(a), std::end(a));
std::list<const char*> v2(std::begin(b), std::end(b));
std::cout << std::boolalpha
<< std::equal(v1.cbegin(), v1.cend(), v2.cbegin()) << std::endl;
return 0;
}
Which yields false
.
So the answer of this exercise depends. But I think the first situation is just a coincidence and should be avoided;
NOTE: If we define a
and b
as pointer array, then the result is true
again.
const char *a[3] = {"A", "B", "C"};
const char *b[3] = {"A", "B", "C"};
So literals of same contents pointed to by pointers share the same memories, but literals in arrays are stored individually.