function problem

Started by
5 comments, last by Spoonbender 16 years, 2 months ago
Is there anyway I can make it so this function excepts any type without having a seprate function for each type?

std::string make_string(int &in)
{
	std::stringstream buffer;
	buffer << in;
	std::string str = buffer.str();
	buffer.clear();
	return str;
}

Also is there a way I can make it accept an undefined number of pareters which is then sticks together in a string?
Advertisement
template <typename T> std::string make_string(T const& in) {    ...}


As for variable number of arguments, not without pain and type unsafety.

To make it is hell. To fail is divine.

Templates.

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]
[TheUnbeliever]
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