std::string make_string(int &in)
{
std::stringstream buffer;
buffer << in;
std::string str = buffer.str();
buffer.clear();
return str;
}
function problem
Is there anyway I can make it so this function excepts any type without having a seprate function for each type?
Also is there a way I can make it accept an undefined number of pareters which is then sticks together in a string?
template <typename T> std::string make_string(T const& in) { ...}
As for variable number of arguments, not without pain and type unsafety.
Templates.
Incidentally, you're reinventing boost::lexical_cast.
EDIT: For variable parameters, either take a container of the parameters (which, if they're not of the same type, will be very ugly), or provide an overloaded operator (a la boost::format and %) that provides some similar functionality.
EDIT2: Incidentally, the above is a minimally-altered copy-and-paste of your code above. Antheus makes a number of relevant points below.
[Edited by - TheUnbeliever on February 19, 2008 8:36:06 AM]
template <class T> std::string make_string(T &in){ std::stringstream buffer; buffer << in; std::string str = buffer.str(); buffer.clear(); return str;}
Incidentally, you're reinventing boost::lexical_cast.
EDIT: For variable parameters, either take a container of the parameters (which, if they're not of the same type, will be very ugly), or provide an overloaded operator (a la boost::format and %) that provides some similar functionality.
EDIT2: Incidentally, the above is a minimally-altered copy-and-paste of your code above. Antheus makes a number of relevant points below.
[Edited by - TheUnbeliever on February 19, 2008 8:36:06 AM]
Quote:Original post by Sync Views
Is there anyway I can make it so this function excepts any type without having a seprate function for each type?
Yes, you can use a templated function:
template <typename T>std::string make_string(const T &in){ //...}
Quote:Also is there a way I can make it accept an undefined number of pareters which is then sticks together in a string?
There is, I'm thinking var-args. I seriously wouldn't touch that little piece of evil though.
Why can't you just use a std::stringstream directly? You can use the << operator more than once on one line:
buffer << value1 << value2 << value3;
Quote:template <class T> std::string make_string(T &in){ std::stringstream buffer; buffer << in; std::string str = buffer.str(); // redundant copy buffer.clear(); // redundant, buffer will be deallocated at end of this function return str;}
// in parameter is const, so that you can safely use things like this:// make_string( std::string("Hello World") )// which would not be allowed otherwisetemplate <class T> std::string make_string(const T &in){ // make initial buffer large enough to not require redundant allocations std::stringstream buffer(32); // write the data buffer << in; // return copy of contents return buffer.str(); }
Quote:Original post by Sync Views
Also is there a way I can make it accept an undefined number of pareters which is then sticks together in a string?
You do not want to do this. There is a reason the C++ standard library did not introduce any new functions that work that way, only keeping the C ones for backwards compatibility.
Even if you didn't want to just use a stream manually, you could just call the function several times and concatenate the strings with operator+.
Or you could try something like this:
class StringBuilder { std::stringstream buffer; StringBuilder(const StringBuilder&); StringBuilder& operator=(const StringBuilder&); public: template <typename T> explicit StringBuilder(const T& t) { (*this)(t); } template <typename T> StringBuilder& operator()(const T& t) { buffer << t; return *this; } operator std::string() const { return buffer.str(); }};// We use this template for type inference.template <typename T>StringBuilder& make_string(const T& t) { return StringBuilder(t);}const int answer = 42;const std::string the_big_parade = make_string(answer * 2 - 8)(' ')("trombones");
Single-argument version:
std::string str = boost::lexical_cast<std::string>(in);
Multiple arguments:
std::stringstream buffer; buffer << in1 << in2 << in3 << in4; std::string str = buffer.str();
In short, you're using stringstream to reinvent a more primitive and clumsier version of lexical_cast, and then using *that* to reinvent stringstream. That could be considered a bit silly. [wink]
boost::lexical_cast already lets you convert a single argument to a string. And stringstream is *meant* to handle multiple arguments easily.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement