By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,197 Members | 1,151 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,197 IT Pros & Developers. It's quick & easy.

best efficient and readable way to concatenate strings (or the best trade-offs)

P: n/a
Since C++ (and STL) have many ways to do string concatenation, I want
to hear (read) from you how you do to concatenate strings with other
strings and other types. The approaches I know are:

-- ostringstream
this does the job well, but:
* all types involved have to support operator<<
* we will lose some readibility in the code because we will always
have to create a temp object to do the concatenation

int n;
float x;
....
ostringstream temp;
temp << "we bought " << n << " items at " << x << " price";
notebook.add(temp.str());
// three liner :(
-- string::operator+
most advantage is we can built all the string using a one liner and
passing the result to string const &, but:
* we have to ensure all members are of string type
* to achieve that, we can use boost::lexical_cast or custom functions
to convert our types/classes to string

int n;
float x;
....
notebook.add("we bought " + toString(n) + " items at " + toString(x) +
" price");
// one liner!! :)

(but is there actually a gain doing that?)

and we have to implement toString(). which way is better?
lexical_cast? ostringstream? overloading (or specializing) for each
involved types? (ints and floats can be converted faster using some
hacks)
-- ostringstream wrapped in a (family) of functions
this technique combines the stream versatility with the oneliner
concatenation thing, but without RVO, I am not sure we will gain
anything:

int n;
float x;
....
notebook.add(concat("we bought ",n," items at ",x," price"));
// one liner!! :)

template<typename A, typename B, typename C, typename D>
string concat(A a, B b, C c, D d) {
ostringstream temp;
temp << a << b << c << d;
return temp.str();
}

this works, but one does not need to be a genius to figure out we have
to define a family of concat functions to handle the different number
of parameters

any ideas?

thanks!!!

Diego
HP

Jun 18 '07 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Diego Martins wrote:
Since C++ (and STL) have many ways to do string concatenation, I want
to hear (read) from you how you do to concatenate strings with other
strings and other types. The approaches I know are:
[...]
any ideas?
Just another way:
boost.format <http://www.boost.org/libs/format/index.html>

Use what is most readable and optimize when your profiler says so.

--
Thomas
http://www.netmeister.org/news/learn2quote.html
Jun 18 '07 #2

P: n/a
On 2007-06-18 22:32, Diego Martins wrote:
Since C++ (and STL) have many ways to do string concatenation, I want
to hear (read) from you how you do to concatenate strings with other
strings and other types. The approaches I know are:
[snip ostringstream]
-- string::operator+
most advantage is we can built all the string using a one liner and
passing the result to string const &, but:
* we have to ensure all members are of string type
* to achieve that, we can use boost::lexical_cast or custom functions
to convert our types/classes to string

int n;
float x;
...
notebook.add("we bought " + toString(n) + " items at " + toString(x) +
" price");
// one liner!! :)

(but is there actually a gain doing that?)

and we have to implement toString(). which way is better?
lexical_cast? ostringstream? overloading (or specializing) for each
involved types? (ints and floats can be converted faster using some
hacks)
If you are mainly concerned with user defined types you can implement

std::string operator+(const std::string&, const myType&)
and
std::string operator+(const char*, const MyType&)

which would make it possible to write things like:

std::cout << "Value: " + myVal + "\n";

where myVal is of type MyType.

--
Erik Wikström
Jun 18 '07 #3

P: n/a
Diego Martins wrote:
Since C++ (and STL) have many ways to do string concatenation, I want
to hear (read) from you how you do to concatenate strings with other
strings and other types. The approaches I know are:

-- ostringstream
this does the job well, but:
* all types involved have to support operator<<
* we will lose some readibility in the code because we will always
have to create a temp object to do the concatenation

int n;
float x;
...
ostringstream temp;
temp << "we bought " << n << " items at " << x << " price";
notebook.add(temp.str());
// three liner :(
-- string::operator+
most advantage is we can built all the string using a one liner and
passing the result to string const &, but:
* we have to ensure all members are of string type
* to achieve that, we can use boost::lexical_cast or custom functions
to convert our types/classes to string

int n;
float x;
...
notebook.add("we bought " + toString(n) + " items at " + toString(x) +
" price");
// one liner!! :)

(but is there actually a gain doing that?)

and we have to implement toString(). which way is better?
lexical_cast? ostringstream? overloading (or specializing) for each
involved types? (ints and floats can be converted faster using some
hacks)
-- ostringstream wrapped in a (family) of functions
this technique combines the stream versatility with the oneliner
concatenation thing, but without RVO, I am not sure we will gain
anything:

int n;
float x;
...
notebook.add(concat("we bought ",n," items at ",x," price"));
// one liner!! :)

template<typename A, typename B, typename C, typename D>
string concat(A a, B b, C c, D d) {
ostringstream temp;
temp << a << b << c << d;
return temp.str();
}

this works, but one does not need to be a genius to figure out we have
to define a family of concat functions to handle the different number
of parameters

any ideas?

thanks!!!

Diego
HP
I'm a fan of classes like the following:
#include <sstream>
#include <string>

class concat
{
public:
template <typename T>
explicit concat(const T & t)
{
m_out << t ;
}

template <typename T>
concat & operator()(const T & t)
{
m_out << t ;
return *this ;
}

std::string str() const
{
return m_out.str() ;
}
private:
std::ostringstream m_out ;
} ;

#include <iostream>

int main()
{
int n = 4 ;
float x = .99 ;
std::string test = concat("We bought ")(n)(" items at ")(x)("
price").str() ;
std::cout << test << std::endl ;
}
Jun 19 '07 #4

P: n/a
Diego Martins wrote:
Since C++ (and STL) have many ways to do string concatenation, I want
to hear (read) from you how you do to concatenate strings with other
strings and other types. The approaches I know are:

-- ostringstream
this does the job well, but:
* all types involved have to support operator<<
* we will lose some readibility in the code because we will always
have to create a temp object to do the concatenation

int n;
float x;
...
ostringstream temp;
temp << "we bought " << n << " items at " << x << " price";
notebook.add(temp.str());
// three liner :(
-- string::operator+
most advantage is we can built all the string using a one liner and
passing the result to string const &, but:
* we have to ensure all members are of string type
* to achieve that, we can use boost::lexical_cast or custom functions
to convert our types/classes to string

int n;
float x;
...
notebook.add("we bought " + toString(n) + " items at " + toString(x) +
" price");
// one liner!! :)

(but is there actually a gain doing that?)

and we have to implement toString(). which way is better?
lexical_cast? ostringstream? overloading (or specializing) for each
involved types? (ints and floats can be converted faster using some
hacks)
-- ostringstream wrapped in a (family) of functions
this technique combines the stream versatility with the oneliner
concatenation thing, but without RVO, I am not sure we will gain
anything:

int n;
float x;
...
notebook.add(concat("we bought ",n," items at ",x," price"));
// one liner!! :)

template<typename A, typename B, typename C, typename D>
string concat(A a, B b, C c, D d) {
ostringstream temp;
temp << a << b << c << d;
return temp.str();
}

this works, but one does not need to be a genius to figure out we have
to define a family of concat functions to handle the different number
of parameters

any ideas?

thanks!!!

Diego
HP
(Apologies if this message comes through twice. I'm having server
troubles.)

I'm a fan of the following syntax for operations that can take an
indefinite number of parameters:
#include <sstream>
#include <string>

class concat
{
public:
template <typename T>
explicit concat(const T & t)
{
m_out << t ;
}

template <typename T>
concat & operator()(const T & t)
{
m_out << t ;
return *this ;
}

std::string str() const
{
return m_out.str() ;
}
private:
std::ostringstream m_out ;
} ;

#include <iostream>

int main()
{
int n = 4 ;
float x = .99 ;
std::string test = concat("We bought ")(n)(" items at ")(x)("
price").str() ;
std::cout << test << std::endl ;
}

--
Alan Johnson
Jun 19 '07 #5

P: n/a
On Jun 18, 6:18 pm, Alan Johnson <a...@yahoo.comwrote:
I'm a fan of the following syntax for operations that can take an
indefinite number of parameters:
[snip]
int main()
{
int n = 4 ;
float x = .99 ;
std::string test = concat("We bought ")(n)(" items at ")(x)("
price").str() ;
std::cout << test << std::endl ;
}
thanks for all responses. the above approach is very nice. I liked the
boost::format too (seems to be very powerful)

I believe the syntax above could be improved to something like this:
std::string test = concat("we bought") + n + " items at " + x + "
price";

concat class must have a templated operator+() as a member function
template<typename T>
concat & concat::operator+(T value) { stream << value; return *this; }

and an operator string to retrieve/compute the result
string concat::operator string(); { return stream.str(); }
if optimization is an issue, we might find a way to use a vector of
pointers (and typeinfos? o__O) to concat all members at a time in the
operator string (a custom concatenation? a reserve and vector of
chars? it could be trickier than one can imagine..)

more ideas?
Diego

Jun 19 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.