Probably the most common easy way wraps essentially your second choice into a template named
lexical_cast, such as the one in Boost, so your code looks like this:
int a = 10;
string s = lexical_cast<string>(a);
One nicety of this is that it supports other casts as well (e.g., in the opposite direction works just as well).
Also note that although Boost lexical_cast started out as just writing to a stringstream, then extracting back out of the stream, it now has a couple of additions. First of all, specializations for quite a few types have been added, so for many common types, it's substantially faster than using a stringstream. Second, it now checks the result, so (for example) if you convert from a string to an
int, it can throw an exception if the string contains something that couldn't be converted to an
1234 would succeed, but
123abc would throw).
As of C++11, there's a
std::to_string function overloaded for integer types, so you can use code like:
int a = 20;
std::string s = to_string(a);
The standard defines these as being equivalent to doing the conversion with
sprintf (using the conversion specifier that matches the supplied type of object, such as
int), into a buffer of sufficient size, then creating an
std::string of the contents of that buffer.