Why is it not possible to pass an int (representing an ASCII character) to std :: string without curly braces wrapped around int?

int main() { std::string A; A += (std::string)65; std::cout << A; } 

The code above does not work. It throws a compiler error. But the code below works.

 int main() { std::string A; A += (std::string){65}; std::cout << A; } 

When I wrap 65 curly braces, this is interpreted as ASCII A as I wanted, but without curly braces the program does not work. I also tried putting a few numbers in braces, for example:

 int main() { std::string A; A += (std::string){65, 66}; std::cout << A; } 

This will print AB. I just hope someone can clarify this for me.

+6
source share
5 answers

The second and third job because of this constructor:

 basic_string( std::initializer_list<CharT> init, const Allocator& alloc = Allocator() ); 

That is, whenever the compiler sees curly braces, it converts {...} to std::initializer_list<T> for a suitable T.

In your case, it is converted to std::initializer_list<char> , which is then passed to the aforementioned constructor std::string .

Since there is an overload += that takes std::initializer_list<char> :

 basic_string& operator+=( std::initializer_list<CharT> ilist ); 

you can write this:

 std::string s; s += {65}; s += {66, 67}; 

That should work too.

Note that you can also write this:

 s += 65; 

Even this will work, but for another reason - it causes the following overload:

 basic_string& operator+=( CharT ch ); 

In this case, 65 (which is int ) is converted to type char .

Hope this helps.

+6
source

(std::string){65, 66} is a C99 literal, not a valid C ++. Some C ++ compilers support it as an extension, but all of them should complain about fairly pedantic settings.

std::string{65, 66} (or just std::string{65} ) works because they create a temporary std::string using its constructor initializer_list<char> .

std::string does not have a constructor taking an integer (or a char , for that matter), so your composition does not work.

In addition, A += 65; works because string has an overloaded operator+= accepting char . (Unfortunately, this also means that A += 3.1415926; "works" too.)

And similarly, A += {65, 66}; will also work because string has an overloaded operator+= accepting initializer_list<char> .

+3
source

The expression (std::string)65 is cast, i.e. You are trying to convert the number 65 to std::string . Your first example does not work, because int not converted to std::string , since std::string does not have a constructor that accepts an integer.

Your second and third example works with A+= (std::string){65} means "build a temporary line through your initializer list constructor (No. 9 here ) and add it to A ". Note that you could just write A+= {65} , and no temporary ones will be created, since you directly call std::string::operator+= in the list of initializers, no. 4 here .

+3
source

The first tries to rethink 65 as std::string .
This is not possible, since integers and std::string completely unrelated.

The second creates an instance of std::string , passing 65 its constructor.

The second one works because it is not cast.

If you drop unnecessary parentheses, it becomes clearer that this is not a throw - this is equivalent

 A += std::string{65}; 

and

 A += std::string('A'); 
+1
source

In the first case, you are using C-style, you are not creating std::string , just trying to get 65 to be std::string .

Using curly braces to initialize calls initializer_list ctor, so in the second and third examples you actually create std::string . That is why it works.

+1
source

Source: https://habr.com/ru/post/985572/


All Articles