MESSAGE
DATE | 2011-07-07 |
FROM | Ruben Safir
|
SUBJECT | Subject: [NYLXS - HANGOUT] (fwd) Re: iostream manipulator construction and design
|
-- forwarded message -- Path: reader1.panix.com!panix!usenet.stanford.edu!postnews.google.com!j28g2000vbp.googlegroups.com!not-for-mail From: Michael DOUBEZ Newsgroups: comp.lang.c++ Subject: Re: iostream manipulator construction and design Date: Wed, 6 Jul 2011 01:00:41 -0700 (PDT) Organization: http://groups.google.com Lines: 116 Message-ID: <37a44930-d9e1-4c9b-b06d-fc0204ae23a7-at-j28g2000vbp.googlegroups.com> References: NNTP-Posting-Host: 62.160.54.163 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1309939340 12470 127.0.0.1 (6 Jul 2011 08:02:20 GMT) X-Complaints-To: groups-abuse-at-google.com NNTP-Posting-Date: Wed, 6 Jul 2011 08:02:20 +0000 (UTC) Complaints-To: groups-abuse-at-google.com Injection-Info: j28g2000vbp.googlegroups.com; posting-host=62.160.54.163; posting-account=4_dwSAoAAAD_OEYz89wEMQOvnJlm6isC User-Agent: G2/1.0 X-Google-Web-Client: true X-Google-Header-Order: HUALESRCNK X-HTTP-UserAgent: Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0,gzip(gfe) Xref: panix comp.lang.c++:1087311
On Jul 6, 4:55=A0am, Ruben Safir wrote: > I've covered the iostream operations in Stroustrup but there is a section > that I'm failing to understand in section 21.4.6.1 (of the third edition > of C++ - The Programming Language) which I hope that someone can help > me decipher. =A0The section discusses Manipultors that take arguments and > Stroustrup states > > > "Manipulators that take arguments can also be useful. =A0For example, we > might want to write > > =A0 =A0cout << setprecision(4) << angle; > > to print the value of the floating-point variable angle with four > digits. > > To do this, setprecision must return an object that is initialized by 4 > and that calls cout::setprcision when involked. =A0Such a manipulator is = a > function object thatr is involed by << rather than by (). =A0The exact > tyoe of function object is implementation-defined, but it might be > defined like this: > > =A0 =A0struct smanip{ > =A0 =A0 =A0 ios_base& (*f)(ios_base&, int); //function to be called > =A0 =A0 =A0 int i; > > =A0 =A0 =A0 smanip(ios_base& (*ff) (ios_base&, int), int ii) : f(ff, i(ii= ){} > =A0 =A0}; > > =A0 =A0template > =A0 =A0ostream& operator<<(ostream& os, smanip& m) > =A0 =A0{ > =A0 =A0 =A0 return m.f(os, m.i); > =A0 =A0} > > The smanip constructor stores its arguments in f and i and the > operator<< calls f(i). =A0We can now define setprecision() like this: > > =A0 =A0ios_base& set_precision(ios)base& s, int n) =A0//helper > =A0 =A0{ > =A0 =A0 =A0 return s.setprecision(n); //call member function > =A0 =A0} > > =A0 =A0inline smap setprecision(int n) > =A0 =A0{ > =A0 =A0 =A0 =A0 =A0return smanip(set_precision, n); > =A0 =A0} > > We can now write: > =A0 =A0cout << setprecision(4) << angle; > " =A0 >
> > What don't understand a couple of things here, and this might be an > accumulation of increasing confusion on my part as I've continued > through this chapter. > > First, I just don't understand what the problem is that is being solved.
The problem being solved is being able to use a parametrized modifier with the same syntax. By example, if you want to uppercase your output, you write: out< This works because ostream (in fact basic_ostream<>) defines an overload like
basic_ostream<>& operator<<(ios_base& (*pf)(ios_base&)) { *pt(*this); return *this; }
And std::uppercase simply set the relevant flag ios_base& std::uppercase(ios_base& os) { os.setf(ios_base::uppercase); return os; }
> Why can't a manipulator just take an argument of an int and return a > base_stream object, like the manipulators that don't take an argument?
But now, if you want a parameter to uppercase: ios_base& set_uppercase(ios_base& os, int isUppercase) { if(isUppercase)os.setf(ios_base::uppercase); else os.unsetf(ios_base::uppercase); return os; }
You cannot directly use set_uppercase because, there is no matching overload in ostream. C++ provides a magic implementation specific class called smanip which provide a mechanism for calling your function.
smanip setUppercase(bool b) { return smanip(set_uppercase, b); }
> Secondly, the exqmple completely befuddles me. =A0I'm guessing that don't > understand the order of operations of > > =A0 =A0cout << setprecision(4) << angle; > > =A0 =A0is ostream<< called first and then the function setprecision?
No, it can help if you rewrite it with function call: operator<<( operator<<(cout ,setprecision(4)) , angle );
-- Michael -- end of forwarded message --
|
|