6
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 the 65 in curly braces, it is interpreted as an ASCII A like I wanted it to be, but without the curly braces, the program doesn't work. I also tried putting multiple numbers in the braces, like so:

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

That would print out AB. I just hope someone can clear this up for me.

5 Answers 5

6

The second and third work because of this constructor:

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

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

In your case, it converts to std::initializer_list<char> which then gets passed to the above mentioned constructor of std::string.

Since there exists an overload of += which 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 as well.

Note that you can also write this:

s += 65; 

Even this will work, but for a different reason — it will invoke the following overload:

basic_string& operator+=( CharT ch ); 

In this case, 65 (which is int) converts into char type.

Hope that helps.

Sign up to request clarification or add additional context in comments.

1 Comment

I was also reading about uniform initialization, would this be considered it?
3

(std::string){65, 66} is a C99 compound literal, and not valid C++. Some C++ compilers support it as an extension, but they should all complain with sufficiently pedantic settings.

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

std::string has no constructor taking an integer (or a char, for that matter), so your cast doesn't work.

Also, A += 65; works as well, because string has an overloaded operator+= taking a 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+= taking an initializer_list<char>.

Comments

3

The expression (std::string)65 is a cast, i.e. you are trying to convert the number 65 to an std::string. Your first example doesn't work because an int is not convertible to an std::string , since std::string does not have any constructor that takes an integer.

Your second and third example work since A+= (std::string){65} means "construct a temporary string via its initializer-list constructor (no. 9 here) and append it to A". Note that you could've just written A+= {65}, and no temporary will be constructed, since you invoke directly std::string::operator+= on a initializer list, no. 4 here.

2 Comments

No temporary string is constructed in A+= {65}.
@T.C. You're right, I edited, it was not equivalent.
1

The first one attempts to reinterpret 65 as std::string.
This is not possible, as integers and std::strings are completely unrelated.

The second one constructs an instance of std::string, passing 65 to its constructor.

The second one works because it is not a cast.

If you drop the unnecessary parentheses, it becomes clearer that it's not a cast - it's equivalent to

A += std::string{65}; 

and to

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

Comments

1

In the first case you're using a C-style cast, you're not constructing a std::string merely trying to force 65 to be a std::string.

Using curly braces for initialization invokes the initializer_list ctor so in the second and third example you're actually constructing a std::string. That's why it works.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.