Sign in to follow this  
Sync Views

function problem

Recommended Posts

Sync Views    139
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?

Share this post


Link to post
Share on other sites
TheUnbeliever    963
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]

Share this post


Link to post
Share on other sites
dmatter    4844
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;

Share this post


Link to post
Share on other sites
Antheus    2409
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 otherwise
template <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();
}

Share this post


Link to post
Share on other sites
Zahlman    1682
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");

Share this post


Link to post
Share on other sites
Spoonbender    1258

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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this