Reputation: 83404
I'm just now seeing another naive C++ code using sprintf to append C builtins into an array of chars, and I guess enough is enough.
I could help providing with simple, lightweight, appending and non-formatting functions for std::string
, but as it would be check-in-ed into the team's common code, I want it to be perfect, so I need some advice on the interface of this feature (i.e. not on the actual implementation).
The following could be possible (I did not test it, it's just a hunch):
+=
" operator (probably in another namespace than std or global)<<
" operator (again, in another namespace)What would be the pros and the cons of each solution (I have a preference for "+=
", or even "<<
") ?
using namespace SomeNamespace ;
as its done for the <utility>
's rel_ops namespace)std::string
which is not able, natively, to handle other types than itself, char
and char *
. I want to extend that to handle other simple types..str()
to put it inside a string, etc. etc.), and the last thing I want is an syntactic sugared inline function instanciating a stringstream at each call). As you can see in the example below, the stringstream solution is too verbose:.
// sprintf-like code with a char[] buffer:
sprintf(buffer, "%d", myDouble) ;
// stream-like code with a std::string buffer:
std::stringstream str ;
str << myDouble ;
buffer = str.str() ;
// example of desired code with a std::string buffer:
buffer += myDouble ;
Upvotes: 3
Views: 6510
Reputation: 6055
What about boost::format
? Then you can write:
std::string first("world");
std::string s = (boost::format("hello %1%") % first).str();
Or create a wrapper class which you can use like so:
int i(2);
std::string s = (Format() + "Hello " + first + " " + i).str();
And Format()
something like (without boost) :
class Format
{
public:
template <typename T>
Format &operator+(const T& v) {
m_sstr << v;
return *this;
};
const std::string &str() const { return m_sstr.str(); };
private:
std::stringstream m_sstr;
};
Upvotes: 3
Reputation: 5530
C++11 comes with an overloaded set of std::to_string functions.
example prototype:
std::string to_string( int value );
They are allowed to be overriden by the user (in C++11). You would need your own namespace for now.
You could implement your own set for the types of your choice. It would make for future-proof code.
you would use the code as:
std::string s;
s+=std::to_string(1);
Upvotes: 3
Reputation: 9969
boost::lexical_cast provides a potential model for you here - write a function that can handle any of the datatypes you need, turn them into a string in the appropriate format for your purposes (and you can optimise that as much as you need to/are able to), and return them for use with operator+(string, string).
Specialise the function per type either with normal overloading or template specialisations according to your preference. lexical_cast uses templates so it can handle absolutely anything via whatever stream operators happen to be defined, but your use case is far narrower than this, and so you definitely can get some more performance out of it.
Upvotes: 0
Reputation: 28728
I would use ostringstream
and stream manipulators to replace sprintf
. It's not worth reinventing the wheel.
Upvotes: 3