I am studying the C++ Primer 5th edition. On page 479, it mentions that
string sum = accumulate(v.cbegin(), v.cend(), "");
is not correct sinceno + on const char*
for "";
The type of v
is a sequential container such as a vector.
I found that using double quotes to create a string is dangerous, especially for the condition that you use generic algorithm, since it requires the objects' defined operator.
But I can't figure out what the description no + on const char*
means?
Will it call the constructor string (const char* s);
which is defined in c-string?
I think that's what the compiler does as it interprets the string which are initialized with quotes in C++.
Should we create a string with double quotes? It will cause overriding on operators
failed.
What it's saying is that you can't add pointers to [const] char to each other, nor can you add a char
to a char [const] *
(well, technically, you can add a char to a char *
, but it won't do what you want--it'll basically treat the char *
as if it points to the beginning of an array, and treat the char
as an index into that array, so the result will be a char *
offset by some distance from the original, where the distance is equal to the encoded value of the char you added).
std::accumulate
deduces the type it should use for the summation from the type of the value you pass as the third parameter. It tries to add things using that type, then when it's done, it attempts to return that value (then, in this case the assignment would attempt to convert char const *
to std::string
). That final conversion would work fine, but the intermediate additions would not.
To make it work, you need to pass an actual std::string
as the initial value:
string sum = accumulate(v.cbegin(), v.cend(), string());
This way it will deduce the summation type as std::string
, so it'll be adding items to a string instead of trying to add to a char const *
. If you're compiler is new enough, you could get the same effect with:
string sum = accumulate(v.cbegin(), v.cend(), ""s);
C++11 added a "user defined literal" feature that allows a suffix like this to invoke a constructor for an object type. C++14 added a number of predefined suffixes like this, including 2 that use the s
suffix like this--this one (for a string literal) creates a std::string
. The other (for integers) creates a timing value used with the std::chrono
timing classes/functions, so 3s
means "three seconds".