How to write a std::stringstream one-liner ?

D

dmtr

I'd like to write a one liner:

But apparently I can't. I'm getting:
Is there any way to do it without declaring "std::stringstream s;"
explicitly? Or there is simply no way to write simple formatting code
"'Value = %d' % 1" in one line without extra clutter? (I know, I
know, I should just switch to python and avoid C++ entirely, but all
this legacy stuff is still in ugly, slow and unintuitive C++ :-/)

-- Cheers, Dmitry
 
R

rep_movsd

The return value of using << on stringstream is not a stringstream&
but an ostream& which has no .str()

A way to achieve your "one liner" is :

((ostringstream&)(ostringstream() << "x")).str();

But it's really ugly and I question the whole philosophy of writing
one liners in C++, You have Perl and APL derived languages for that...
 
F

Francesco S. Carta

I'd like to write a one liner:


But apparently I can't. I'm getting:

Is there any way to do it without declaring "std::stringstream s;"
explicitly? Or there is simply no way to write simple formatting code
"'Value = %d' % 1" in one line without extra clutter? (I know, I
know, I should just switch to python and avoid C++ entirely, but all
this legacy stuff is still in ugly, slow and unintuitive C++ :-/)

In order to easily write one liners as you ask, you need to create an
helper class. We had some discussions about this around one year ago,
and we have come to a working and compact solution (at least I recall it
to be a working solution).

For the discussion see this thread:

http://groups.google.com/group/comp.lang.c++/browse_frm/thread/fc658b19085bc581

and for the solution see this post in particular:

http://groups.google.com/group/comp.lang.c++/msg/77e566c11ce93120

I hope not to have mistaken the links, try the code that you find in
there and check out if that fulfills your needs.

Cheers
 
J

James Kanze

I'd like to write a one liner:
But apparently I can't. I'm getting:

There are actually two problems with the above (and you're
compiler is apparently faulty, since it didn't find the first):

-- std::stringstream() is a temporary, which cannot bind to
a non-const reference. The << operator which takes a string
literal is a non-member function whose first argument is
a non-const reference.

-- The return value of << is always an std::eek:stream&, not an
std::stringstream&, so it doesn't have an str() function.
Is there any way to do it without declaring "std::stringstream s;"
explicitly?

Yes, but it's a bit painful. First, you have to call a member
function which returns a non-const reference on the temporary,
e.g.:
std::eek:stringstream().flush() << ...
You can call member functions on temporaries, and since the
function returns a reference, there's no longer any question of
binding the temporary to a reference. (The compiler just uses
the reference you gave it.) Then, you have to reconvert the
final results into an ostringstream, using a static_cast:

static_cast<std::eek:stringstream&>(std::eek:stringstream().flush() <<
"Value = " << 1).str()

Personally, I'd recommend some sort of helper class.
Or there is simply no way to write simple formatting code
"'Value = %d' % 1" in one line without extra clutter? (I know, I
know, I should just switch to python and avoid C++ entirely, but all
this legacy stuff is still in ugly, slow and unintuitive C++ :-/)

Ugly and unintuitive, maybe, but certainly not slow (and done
correctly, for a large application, the results are more robust
and more maintainable than they would be in Python).
 
D

dmtr

There are actually two problems with the above (and you're
compiler is apparently faulty, since it didn't find the first):

-- std::stringstream() is a temporary, which cannot bind to
a non-const reference. The << operator which takes a string
literal is a non-member function whose first argument is
a non-const reference.

GCC version 4.4.1. And VC++ 2008 gives the same error too.

Yes, but it's a bit painful. First, you have to call a member
function which returns a non-const reference on the temporary,
e.g.:

static_cast<std::eek:stringstream&>(std::eek:stringstream().flush() <<
"Value = " << 1).str()

Eww... But yes, that's what I was looking for, a one liner that uses
only language/standard library constructs. Only this one is too far on
the ugly side. Is there something in the TR1 that could give a better
solution? And if no, any particular reasons why it is not there?

Ugly and unintuitive, maybe, but certainly not slow (and done
correctly, for a large application, the results are more robust
and more maintainable than they would be in Python).

Let me agree and disagree. C++ itself is intuitive and fast. But the
std library is neither. And it's ugly too :-/
As to more maintainable... hard to tell. Hellish portability and
interoperability issues, even for well-written project. Integration of
any third party libraries/components is usually difficult (primarily
because custom type conventions/helpers/etc are used all other the
place).
 
J

Joshua Maurice

GCC version 4.4.1. And VC++ 2008 gives the same error too.



Eww... But yes, that's what I was looking for, a one liner that uses
only language/standard library constructs. Only this one is too far on
the ugly side. Is there something in the TR1 that could give a better
solution? And if no, any particular reasons why it is not there?


Let me agree and disagree. C++ itself is intuitive and fast. But the
std library is neither. And it's ugly too :-/

Hey now! The C++ standard containers are quite fast implementations of
their specs for all of my testing, experience, and usage. Intuitive is
a whole other question though. I think they're pretty good, though I
really think overloads for range objects would help a lot.

Then there's the iostream library, which I still don't really
understand even after reading the standard and various suggested
breakdowns of it. I've come to appreciate aspects of it, but I'm with
you in agreeing that the iostream library overall is an abomination,
poorly documented, with poor function names, not intuitive, with
basically a kitchen sink approach. Some people on here say that they
use locales, facets, etc., but I remain unconvinced that anyone in a
serious, commercial, portable product actually uses any of the
standard culture portability layer like locales and facets. They would
have to roll their own, especially considering Unicode support.
 
D

dmtr

Hey now! The C++ standard containers are quite fast implementations of
their specs for all of my testing, experience, and usage. Intuitive is
a whole other question though. I think they're pretty good, though I
really think overloads for range objects would help a lot.

Nah. I'll give you an example. For instance you need to loop through
two vectors. What would you do? Efficient solution would be
concatenating iterator. But AFAIK there is no such thing in the
standard library. And this ugliness and incompleteness would probably
force you into inefficient copy/insert operation. Hence slow. It
doesn't matter that C++ is inherently fast. As long as there is no
convenient and intuitive access to relevant algorithms the resulting
real life code is often quite slow.
 
D

Daniel Pitts

Nah. I'll give you an example. For instance you need to loop through
two vectors. What would you do? Efficient solution would be
concatenating iterator. But AFAIK there is no such thing in the
standard library. And this ugliness and incompleteness would probably
force you into inefficient copy/insert operation. Hence slow. It
doesn't matter that C++ is inherently fast. As long as there is no
convenient and intuitive access to relevant algorithms the resulting
real life code is often quite slow.
Or, I would probably do:
loopThrough(vector1);
loopThrough(vector2);

;-)

Okay, but taking your point at face value, there are some convenient
operations that aren't "simple" to implement, but are missing from the
C++ standard. I believe python has a construct that does what you're
suggesting, so I can see at least one other person thinks its a useful
thing. I can't think of ever needing it myself, but I haven't worked on
all possible problem spaces ;-)
 
M

Michael Doubez

Nah. I'll give you an example. For instance you need to loop through
two vectors. What would you do? Efficient solution would be
concatenating iterator. But AFAIK there is no such thing in the
standard library.

And you wouldn't build a house because you have only bricks ?

The standard library only gives you the basic concepts and building
blocks.
And this ugliness and incompleteness would probably
force you into inefficient copy/insert operation. Hence slow.

Actually, if I had to consider two vectors as one and copy isn't an
option, I would rather build a sequence_view<> that proposes an
interface to chain sequence containers and provide an iterator to
iterate over an aggregate of sequence container of the same type.

But others may have different need and only provide a chain iterator
which is not that hard to implement. Or you may want to iterate other
heterogeneous containers, and so on.
It
doesn't matter that C++ is inherently fast. As long as there is no
convenient and intuitive access to relevant algorithms the resulting
real life code is often quite slow.

The issue is rather that programmers have the possibility to make a
program arbitrarily slow and inefficient. When you restrain the
freedom of the programmer, you can create a lower bound on the damages
he can cause.

IMHO a real drawback of c++ is that we don't have repository for
algorithm/pattern implementation. I think it is because the solution
space in C++ is very large.
AFAIS Boost is the first (arguably) largely accepted C++ code base and
it also only provide higher building blocks (by example iterator
facade to create new iterators).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top