An 11th Way to Convert a char to a string in C++
If by some miracle of search engine optimization you landed here first just googling around for a C++ code snippet or for some reason you found Techie Delight’s listicle 10 ways to convert a char to a string in C++ inadequately delightful, here’s your payoff right out of the gate.
std::string res{'c'};
Great! You’re free to go…
🔗 or: How I Learned that Braces and Parens Aren’t the Same Thing
… but, if you feel like sticking around for a brief debugging fable (perhaps even conveying something of a moral) you’re also welcome to stick around!
The story starts with @rodsan0 & I doing some pair programming on a command line argument parsing tool in our lab’s software library.
One of the POSIX-y features we were working on was support for stringing together single-letter options (a la ls -lvd
).
We found ourselves needing to grab the single-letter chars out of argument strings and then convert them back to strings to do lookups in a command de-aliasing map. “This should be an easy no-brainer thing to do,” we cheerfully assumed.
We poked through the first half of the first page of the Google results for “char to string C++.” The string fill constructor, which takes a repeat-count and a character as arguments, seemed a good fit. Bippity-boppity-boo… here’s what we typed up:
std::string res{1, 'c'};
The lookups weren’t working how we expected, so we tried printing out the lookup keys we were generating. They looked how we would expect, with
std::cout << res << std::endl;
yielding
c
Imagine our surprise 30 minutes later when we discovered that,
res != "c"
Digging in further, we discovered
res.size() == 2
Then, we found that the first character of the generated string was “ASCII Start of Header,” followed by the expected character c
.
Wut.
As these things do when you figure them out, the answer hit us with all of the subtlety of a Hefty bag filled with vegetable soup.
We quickly confirmed that
std::string res{97, 'c'} == "ac"
We weren’t using the fill constructor at all! We were using the initializer list constructor.
To get the fill constructor we expected, we should have been using parens
std::string res(1, 'c');
Simple enough, but how did we end up in this particular time-wasting pickle? Well, being a Good C++ Dilettante, somewhere along the way I had picked up the notion to just always throw braces on when creating new objects and feel like a good modern C++ good boy.
Wow.
Much core guideline “ES.23: Prefer the {}
-initializer syntax”.
Good job me.
After a few months of using braces in place of parens without incident I slid into the alluring notion that they were basically close enought the same thing so I could just not think about using braces.
But, as with all things C++, in ES.23 there is also a clearly documented…
Exception
For containers, there is a tradition for using
{...}
for a list of elements and(...)
for sizes:vector<int> v1(10); // vector of 10 elements with the default value 0 vector<int> v2{10}; // vector of 1 element with the value 10 vector<int> v3(1, 2); // vector of 1 element with the value 2 vector<int> v4{1, 2}; // vector of 2 element with the values 1 and 2
On the plus side, this rabbit hole introduced us to the little “11th Way” initializer list approach the post opened with!
🔗 Lesson of the Day
Anyways, here’s your “so-called promised fable:” doing things to Follow The Rule will only get you so far if you don’t also Understand The Rule.
As Kate Gregory eloquently points out, writing good C++ is an exercise in continually learning C++. In C++ and other (?) parts of life (??), keeping alert for things we do without really understanding should be a launching point to seek out understanding!
Also, braces and parens are not the same thing.
🔗 Let’s Chat
I would love to hear your thoughts, questions, and comments RE: char-to-string conversion & lifelong C++ learning!!!
I started a twitter thread (right below) so we can chat
new #cpp blog post:
— mmore500 (@mmore500) February 26, 2020
* the teeniest, tiniest, most trivial code snippet converting char to string
* 1 quality jif & 3 quality memes
* also Reflections on the perpetual process of learning C++???
https://t.co/elEOckMWzh