On Nov 29, 5:25 pm, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.comwrote:
In the book, C++ Coding Standards book by Hereb Sutter and Andrei
Alexandrescu, in Item 40 on pages 86-87 viz, "Avoid providing implicit
conversions", the authors have advised the use of named functions that
offer conversions instead of conversion operators.
In page 87, example 2: Errors that work.
class String
{
// ...
public:
operator cons char *(); // deplorable form
};
Assume s1, s2 are 'String's:
int x = s1 -s2; // compiles; undefined behaviour
const char *p = s1 - 5; // compiles; undefined behaviour
...
I am NOT going against the authors in asking the following.
However, as a beginner I just to want to know if conversion operators
should be avoided totally ?
Pretty much so. About the only general exception I can think of
is proxies, which only work because of implcit conversions.
Otherwise, there are a few special cases; as a beginner, you
probably don't have to worry much about these, however.
Because, in <istream>, we have operator bool() const; (in the
sentry class)
This helps in
while(cin)
// ...
You're mixing up two things.
In istream and ostream, there is a nested sentry class, which
has an implicit conversion operator to bool. It is used when
writing << and >operators which go directly to the streambuf
(rather than decomposing the operation into << or >on simpler
types). The "standard" idiom here is:
std::ostream&
operator<<( std::ostream& dest, SomeType const& obj )
{
std::ostream::sentry s( dest ) ;
if ( s ) {
// do it...
}
return dest ;
}
Obviously, other alternatives (not involving the explicit
conversion) are possible, but in this (special) case, it really
doesn't matter; the class is designed to be used in one specific
case, and only in one specific case.
Both istream and ostream derive from ios, and ios has an
implicit conversion to void*. This supports idioms such as:
while ( std::cin >someVariable ) ...
or
while ( std::getline( std::cin, line ) ) ...
, the void* acting here as a bool. (The reason bool wasn't used
was because bool is an integral type, and >and << are defined
over it. So in some cases, you could get some strange overload
resolutions, rather than an error from the compiler.)
Whether this is good design or not is very debatable; as a
general rule, it is NOT a good idea to both modify program state
and have flow control in a single line/statement. Something
like:
std::cin >someVariable ;
while ( std::cin.succeeded() ) {
// ...
std::cin >someVariable ;
}
would arguably be better. Similarly, one would like to be able
to use the stream for initialization, and not just to modify
existing variables.
All one can say here is that I/O, in general, is hard, and that
iostreams works a lot better than anything else anyone has
proposed (or what's available in other languages). And the
idiom is ubiquious enough that it doesn't cause problems in
practice; everyone knows it and expects it. Since that's highly
unlikely to be the case for any class you write, you should
probably avoid such things.
So here the standard library uses a conversion operator.
The standard library does a lot of things that aren't
necessarily good practice. (The iostream's part is probably one
of the better parts of it.) But a standard library also obeys
different rules than your code, at least partially. It will be
ubiquious, and it will be well known. Which means that code
using it idiomatically will be readable, regardless of the
conventions. Your code won't have those advantages.
Are there any guidelines as to when the conversion operators
can be defined ?
Yes. Except for proxies and if you're designing the standard
library of a major language, don't. (As with all rules, there
are exceptions. But unless it is obvious that the case must be
an exception, it probably isn't.)
--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34