|
Prev: Nested variable declarations using the same name
Next: A Set of Questions About Console I/O and Structures...
From: Niels Dekker - no return address on 23 Apr 2008 04:14 Does the Standard Library support creating an std::string by means of streaming, without having to declare a *named* ostringstream object? I tried the following: #include <sstream> #include <string> int i = 42; std::string s = (std::ostringstream() << "i = " << i).str(); Of course it didn't compile, because a temporary (std::ostringstream()) cannot be passed as non-const reference to a function (operator<<). Okay, second try, wrapping the ostringstream as follows: template <typename T> class Wrapper { T m_data; public: T & get() { return m_data; } }; std::string s = (Wrapper<std::ostringstream>().get() << "i = " << i).str(); Unfortunately it still didn't compile, because operator<< returns an std::basic_ostream, instead of an std::ostringstream, and therefore it doesn't have an str() member function. Now I wonder, is it safe to cast the stream, returned by operator<< to an ostringstream reference? As follows: std::string s = static_cast<std::ostringstream&>(Wrapper<std::ostringstream>().get() << "i = " << i).str(); At least, it *seems* to work... But is it the proper way to do it? Kind regards, -- Niels Dekker http://www.xs4all.nl/~nd/dekkerware Scientific programmer at LKEB, Leiden University Medical Center [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Martin York on 23 Apr 2008 16:05 On Apr 23, 12:14 pm, "Niels Dekker - no return address" <nore...(a)this.is.invalid> wrote: > Does the Standard Library support creating an std::string by means of > streaming, without having to declare a *named* ostringstream object? I tried > the following: <DELETED> > > At least, it *seems* to work... But is it the proper way to do it? Is your problem that you have other objects of non string types that you want to append onto a string. In this case you could use boost::lexical_cast() std::string s = std::string("i = ").append( boost::lecical_cast<std::string>(i) ); -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Peter Jones on 23 Apr 2008 16:10 "Niels Dekker - no return address" <noreply(a)this.is.invalid> writes: > Does the Standard Library support creating an std::string by means of > streaming, without having to declare a *named* ostringstream object? What's wrong with: ,---- | #include <iostream> | #include <sstream> | #include <string> | | int main (int argc, char *argv[]) | { | std::ostringstream os; | int i = 42; | | os << "i=" << i; | std::string s = os.str(); | | std::cout << s << std::endl; | } `---- Are you just trying to make your code as terse as possible? Why would you want to create a string from an ostringstream without having to use a named ostringstream? -- Peter Jones [pjones at domain below] pmade inc. - http://pmade.com [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Carl Barron on 23 Apr 2008 16:43 In article <480ef5ff$0$14345$e4fe514c(a)news.xs4all.nl>, Niels Dekker - no return address <noreply(a)this.is.invalid> wrote: > Does the Standard Library support creating an std::string by means of > streaming, without having to declare a *named* ostringstream object? I tried > the following: > > #include <sstream> > #include <string> void foo() { > int i = 42; > > std::string s = (std::ostringstream() << "i = " << i).str(); > } No but, most general and easiest solution is to put the ostringstream in a block. void foo() { int i= 42; std::string s; { std::ostringstream oss; oss << "i = " << i ; s = oss.str(); } } this has the same effect as what your errant code is supposed to do. and does not flood the code with temp variables that live longer than needed. that is the ostringstream is destroyed on exit from the short block. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Vidar Hasfjord on 24 Apr 2008 06:12 On Apr 23, 8:14 pm, "Niels Dekker - no return address" <nore...(a)this.is.invalid> wrote: > std::string s = (std::ostringstream() << "i = " << i).str(); > Of course it didn't compile, because a temporary (std::ostringstream()) cannot > be passed as non-const reference to a function (operator<<). Well, that is not the case on the implementations I use (VC7.1/VC9.0). The << operator is implemented as a member of ostream; which does bind to temporaries; so this works fine: ostringstream () << "i = " << i; // compiles I don't know if the standard mandates this or not though. > Unfortunately it still didn't compile, because operator<< returns an > std::basic_ostream, instead of an std::ostringstream, and therefore it doesn't > have an str() member function. Yes, the reason it doesn't work is type erasure. The first application of << returns ostream&, and ostringstream::str can not be applied to an ostream. > Now I wonder, is it safe to cast the stream, returned by operator<< to an > ostringstream reference? Yes, you can recover the type in this way, but pedantically you should use a dynamic_cast to do so. dynamic_cast <ostringstream&> (ostringstream () << ...).str (); This is ugly and verbose though. An alternative wrapper solution that I use is based on forwarding the << operator call: struct S { // string builder std::ostringstream s; template <typename T> inline S& operator << (const T& v) { using ::operator <<; // Note: Ugly disambiguation. s << v; return *this; } inline operator std::string () const {return s.str ();} }; Usage: string s = S () << "i = " << i; This works for me in practice. But you may stumble into problems caused by less-than-perfect forwarding (e.g. ambiguities). I haven't studied the best solution to this yet. Regards, Vidar Hasfjord -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Next
|
Last
Pages: 1 2 Prev: Nested variable declarations using the same name Next: A Set of Questions About Console I/O and Structures... |