Topic: bool converts ubiquitously making overloading impossible
Author: "Old Wolf" <oldwolf@inspire.net.nz>
Date: Sun, 30 Jan 2005 20:33:47 CST Raw View
hartmut.schaefer@zkb.ch wrote:
> class foo
> {
> public:
> explicit foo( const std::string & pName, int pIsRequired );
> explicit foo( int pValue, const std::string & pName );
> }
>
> foo( false, "b" );
> --- end code ---
>
> This is a messy workaround although, since it doesn't solve the real
> problem (automatic conversion of bool to std::string) but changes an
> unrelated part exploiting the fact that char[] doesn't convert to
int.
> Also, I have to declare the boolean parameters with another than
their
> real (logical) type corrupting clarity and forcing unnecessary
> conversions from the bool value to the int parameter type and then
> back to the bool instance variable type (the latter happening in the
> initializer, not shown in the code).
>
> This solves my overload problem. What I don't understand is why the
> standard forces me to do such messy things or, in other words, why
the
> standard renders it's own achievements (the bool type) useless by
> making bool convert to *everything*. And, what could be the semantic
> content of (automatically!) converting a truth value to void
pointer?!
> What could this pointer point to?
>
> What sense does a bool type make if it isn't *really* distinguishable
> from all other types? It seems less usable than the int it is aimed
to
> replace! In my view, bool should be the dead end of a "one way road"
> meaning that the conversion chain ends there, and there is no way
back
> (other than an explicit user defined conversion from bool *itself*).
You have it the wrong way around. Your problem is caused by
the conversion TO bool, specifically, allowing "b" to match
a bool parameter. The reason your new code works is that you
changed the second parameter of the first foo to be an 'int',
which is NOT matched by a pointer. You could change the 'int'
back to 'bool' in the second foo() and it would still work
correctly.
The conversion FROM bool to std::string is a red herring that
wasn't actually a problem in this specific example. The problem
with the first parameter was the null-pointer-constant to string
conversion, which ought to be outlawed IMHO.
You could remove the red herring by writing foo(0, "b").
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: tslettebo@hotmail.com ("Terje Sletteb ")
Date: Mon, 10 Jan 2005 22:44:23 GMT Raw View
>"Bob Hairgrove" <invalid@bigfoot.com> wrote in message
news:2fn5u05940gp26ofqoctsioqi8vglr24jl@4ax.com...
>On Mon, 10 Jan 2005 18:28:57 GMT, hartmut.schaefer@techemail.com
>(Hartmut Sch fer) wrote:
>>#include <string>
>>
>>class foo
>>{
>> public:
>> explicit foo( const std::string & pName, bool pIsRequired );
>> explicit foo( bool pValue, const std::string & pName );
>>}
>>
>>foo( false, "b" );
>(FWIW, the Comeau compiler agrees with the other ones. :( Here is the
>output):
>"E:\projects\cpp\scratch\conv.cpp", line 10: error: more than one
>instance of
> constructor "foo::foo" matches the argument list:
> function "foo::foo(const std::string &, bool)"
> function "foo::foo(bool, const std::string &)"
> argument types are: (bool, const char [2])
> foo( false, "b" );
To determine if there exists a best match, it may help to write the
conversion sequences involved. From what I can tell, they are (SC = Standard
conversion, such as conversion between built-in types, UDC - User-defined
conversion) (omitting array-to-pointer conversions for simplicity):
(bool, const char *) -> foo( const std::string &, bool):
1: bool -> const char * (SC - null pointer constant) -> std::string (UDC) ->
const std::string & (SC)
2: const char * -> bool (SC)
(bool, const char *) -> foo( bool, const std::string &):
1: bool -> bool (SC - identity)
2: const char * -> std::string (UDC) -> const std::string & (SC)
Now, for one function call to be a better match then another, the conversion
sequence for each parameter in the call shall not be any worse than the
corresponding sequences for the other function, and at least one shall be
better (or some other disambiguating thing, like template/non-template,
etc.).
SC is a better match than UDC, and for parameter 1, the first function has
UDC rank, while the second function has SC rank. However, for parameter 2,
it's the other way around. Hence, there's no function that is a better match
for all parameters, and the call is ambiguous.
Nice puzzle, though. :)
As to the loose conversions in C++, they are in a large degree a heritage
from C (compatibility reasons).
>But you have a point. I can't see how the constructor of std::string
>should be able to take "false" as an argument, because two conversions
>are involved (albeit one implicit, the other user-defined).
Yes, but that's perfectly ok. A user-defined conversion sequence consists of
a standard conversion, followed by a user-defined conversion, followed by
another standard conversion (any of the SCs may be the identity conversion).
Thus, the sequence shown above is ok:
bool -> const char * (SC - null pointer constant) -> std::string (UDC) ->
const std::string & (SC)
However, you can't have two user-defined conversions in a row.
>But I can write:
>#include <string>
>
>class foo
>{
> public:
> foo(bool pValue);
> foo(const std::string & pName);
>}
>
>Both foo("b"); and foo(false); compile equally well here. Obviously,
>the compiler has no trouble disambiguating the two.
Yes, because here, one function call is clearly a better match than the
other.
Regards,
Terje
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nospam@nospam.ucar.edu ("Thomas Mang")
Date: Mon, 10 Jan 2005 22:47:44 GMT Raw View
I am sorry I have to mark my responses with <begin> and <end>. There seem to
be problems in this newsgroup regarding automatically marking text that is
responded at.
"Bob Hairgrove" <invalid@bigfoot.com> schrieb im Newsbeitrag
news:2fn5u05940gp26ofqoctsioqi8vglr24jl@4ax.com...
On Mon, 10 Jan 2005 18:28:57 GMT, hartmut.schaefer@techemail.com
(Hartmut Sch fer) wrote:
>#include <string>
>
>class foo
>{
> public:
> explicit foo( const std::string & pName, bool pIsRequired );
> explicit foo( bool pValue, const std::string & pName );
>}
>
>foo( false, "b" );
<begin>
Correct, ambiguous.
To call the first constructor, the first argument needs a user-defined
conversion sequence, and the second an array-to-pointer conversion, followed
by boolean conversion, meaning a standard conversin sequence with rank of
Conversion.
The second requires an identity conversion for the first parameter, and a
user-defined conversion sequence for the second.
Now for each parameter the conversion sequences are compared.
For the first parameter, we have user-defined conversion sequence vs.
identity conversion. That means the second constructor is a winner here.
For the second parameter, we have Conversion vs. user-defined conversion
sequence. Here, the first constructor is winner.
Since for successful overload resolution, at least one sequence has to be
better, but no worse, the call is ambiguous. It doesn't matter here that the
one standard conversion sequence is of rank Conversion and the other of rank
exact match, because they apply to different parameters.
<end>
Hmm ... explicit is only effective with single-argument constructors,
or constructors where all but the first parameter take default
arguments. Otherwise, it is ignored. But that is irrelevant here.
(FWIW, the Comeau compiler agrees with the other ones. :( Here is the
output):
"E:\projects\cpp\scratch\conv.cpp", line 10: error: more than one
instance of
constructor "foo::foo" matches the argument list:
function "foo::foo(const std::string &, bool)"
function "foo::foo(bool, const std::string &)"
argument types are: (bool, const char [2])
foo( false, "b" );
^
One problem with implicit converting of bool is this -- how many times
have you seen or written something like this:
Object * pObj = Factory::getObject(...);
if (pObj)
{ /* do something with pObj*/ }
We *need* to have implicit conversion to bool for all pointer types,
at least for backwards-compatibility.
But you have a point. I can't see how the constructor of std::string
should be able to take "false" as an argument, because two conversions
are involved (albeit one implicit, the other user-defined). But I can
write:
#include <string>
class foo
{
public:
foo(bool pValue);
foo(const std::string & pName);
}
Both foo("b"); and foo(false); compile equally well here. Obviously,
the compiler has no trouble disambiguating the two. Note that I have
also left off the "explicit" keyword -- although here it might have
made sense!
<begin>
Only one parameter is used. The first constructor only requires a standard
conversion sequence (either array-to-pointer + boolean conversion, or
identity conversion), whereas the second needs a user-defined convesion
sequence. And standard conversion sequence is always better.
Using 'explicit' does not affect this.
<end>
Looks like it's time for the experts now.
<begin>
Well, I responded nevertheless......
<end>
Thomas
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ron@sensor.com (Ron Natalie)
Date: Tue, 11 Jan 2005 03:21:48 GMT Raw View
Hartmut Sch?fer wrote:
> Hello, all,
>
> please consider the following code:
>
Yep, this is why it is sometimes better to use either int
or void* to implement the bool like functionality. You can't
implicitly convert between pointers and ints.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Tue, 11 Jan 2005 05:39:57 GMT Raw View
Bo Persson wrote:
>=20
> But false is a valid null pointer constant (4.10) that can be used by=20
> the std::string(const char*) constructor. Undefined behavior, but of th=
e=20
> "no diagnostics required" kind...
>=20
I think that's the point. It's already little intuitive to have an int=20
converted into a (null) pointer, but having that for a bool violates the=20
principle of least astonishment, IMHO. What if we amend =A74.10 to make a=
n=20
exception for boolean expressions?
Alberto
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Tue, 11 Jan 2005 05:39:45 GMT Raw View
Hartmut Sch?fer wrote:
> Hello, all,
>
> please consider the following code:
>
> --- begin code ---
> #include <string>
>
> class foo
> {
> public:
> explicit foo( const std::string & pName, bool pIsRequired );
> explicit foo( bool pValue, const std::string & pName );
> }
>
> foo( false, "b" );
> --- end code ---
>
> I would expect the second form to win the overload resolution since
> parameter 1 goes without conversion and parameter 2 needs a user
> defined conversion, while the first form too needs a user defined
> conversion (this time for the first parameter) and *additionally* a
> standard conversion (for the second parameter).
The compilers are right.
Informally, it's not enough that one match be "slightly better"
than the other. IT has to be "significantly better", which is
defined in the standard, or the compiler must report an
ambiguity.
This is a good thing. Otherwise, mysterious mismatches would
be a serious source of bugs. PL/I had that problem.
As previously mentioned, "explicit" is meaningless here. Also,
conversion from "const char*[]" to "std::string&" is a user
defined conversion, defined somewhere in an STL include file.
So each match requires a "user defined conversion", which
is ambiguous according to the standard.
John Nagle
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: invalid@bigfoot.com (Bob Hairgrove)
Date: Tue, 11 Jan 2005 17:43:13 GMT Raw View
This seems to work better:
#include <string>
class foo
{
public:
foo( const std::string & pName, int req);
foo( int req, const std::string & pName );
}
foo( false, "b" );
--
Bob Hairgrove
NoSpamPlease@Home.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hartmut.schaefer@zkb.ch
Date: Wed, 12 Jan 2005 19:15:16 GMT Raw View
<<-- message to the moderator of comp.std-c++ -->>
Dear Sir,
I use email since I'm currently unable to reply correctly to usenet
posts through Google Groups. My post wouldn't appear as a reply to the
replied-to post as separate thread.
Could you please post the text below as a reply to my initial post
"bool converts ubiquitously making overloading impossible" in
comp.std.c++ from 2005-01-10 (message
c8fcab4d.0501100824.578751fc@posting.google.com from
hartmut.schaefer@techemail.com).
Thank you, Sincerely
Hartmut Sch=E4fer
<<-- end of message to the moderator of comp.std-c++ -->>
<<-- text of posting to comp.std-c++ -->>
Hi, all,
sorry for the delay, I had posting problems. Thank you all for the
replies, some of which were very educating to me. I now do better
understand over.best.match, and a little also *why* it is defined this
way and not as I thought would be reasonable common sense (that is,
summing up the cost of all conversions before comparing the
alternatives).
Aside, true, the 'explicit' keword isn't necessary in this example. It
was left from my original code in which the second parameter of the
first constructor was optional. (For a clear and uniform look I
decided to tag *all* constructors the same way so it would be
eye-catching that conversions could happen *only* where there is a
constructor *missing* that keyword.)
Now to the problem:
As Bo Person writes,
> false is a valid null pointer constant (4.10)
and this is obviously the problem. Although I didn't and don't yet
understand where (4.10) could apply to bool values.
So, the C++ standard makes me unable to overload on bool, since it
allows bool to convert automatically into and out of almost any other
type (at least those that can be constructed from some pointer type -
that is probably the majority, at least enough to make bool mostly
unusable). I don't understand why the standard defines it this way.
Fortunately, Ron Natalie suggested me an escape: going back to C int
boolean style, throwing away the bool achievement of the C++ standard:
When I change the parameter type from bool to int the code compiles
without ambiguities (and selects the right function, what can be
verified by commenting out it: the other isn't at all considered a
candidate):
--- start code ---
#include <string>
class foo
{
public:
explicit foo( const std::string & pName, int pIsRequired );
explicit foo( int pValue, const std::string & pName );
}
foo( false, "b" );
--- end code ---
This is a messy workaround although, since it doesn't solve the real
problem (automatic conversion of bool to std::string) but changes an
unrelated part exploiting the fact that char[] doesn't convert to int.
Also, I have to declare the boolean parameters with another than their
real (logical) type corrupting clarity and forcing unnecessary
conversions from the bool value to the int parameter type and then
back to the bool instance variable type (the latter happening in the
initializer, not shown in the code).
This solves my overload problem. What I don't understand is why the
standard forces me to do such messy things or, in other words, why the
standard renders it's own achievements (the bool type) useless by
making bool convert to *everything*. And, what could be the semantic
content of (automatically!) converting a truth value to void pointer?!
What could this pointer point to?
What sense does a bool type make if it isn't *really* distinguishable
from all other types? It seems less usable than the int it is aimed to
replace! In my view, bool should be the dead end of a "one way road"
meaning that the conversion chain ends there, and there is no way back
(other than an explicit user defined conversion from bool *itself*).
What do the standard gurus say about this?
Best Regards,
Hartmut Sch=E4fer
<<-- end of text of posting to comp.std-c++ -->>
Freundliche Gr=FCsse
Hartmut Schaefer
Z=FCrcher Kantonalbank, LILPB (656)
Tel. +41 (0) 1 292 71 91, Fax +41 (0) 1 292 86 51
Briefadresse: Neue Hard 9, Postfach, CH-8010 Zuerich,
http://www.zkb.ch
___________________________________________________________________
Disclaimer:
Diese Mitteilung ist nur fuer die Empfaengerin / den Empfaenger
bestimmt.
Fuer den Fall, dass sie von nichtberechtigten Personen empfangen wird,
bitten wir diese hoeflich, die Mitteilung an die ZKB zurueckzusenden
und anschliessend die Mitteilung mit allen Anhaengen sowie allfaellige
Kopien zu vernichten bzw. zu loeschen. Der Gebrauch der Information
ist verboten.
This message is intended only for the named recipient and may contain
confidential or privileged information.
If you have received it in error, please advise the sender by return
e-mail and delete this message and any attachments. Any unauthorised
use or dissemination of this information is strictly prohibited.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: invalid@bigfoot.com (Bob Hairgrove)
Date: Thu, 13 Jan 2005 03:02:55 GMT Raw View
On Wed, 12 Jan 2005 19:15:16 GMT, hartmut.schaefer@zkb.ch wrote:
[snip]
>So, the C++ standard makes me unable to overload on bool, since it
>allows bool to convert automatically into and out of almost any other
>type (at least those that can be constructed from some pointer type -
.. out of, not into ... except for integral types, and anything an
int will automatically convert into (float + double, mostly) ...
>that is probably the majority, at least enough to make bool mostly
>unusable). I don't understand why the standard defines it this way.
>Fortunately, Ron Natalie suggested me an escape: going back to C int
>boolean style, throwing away the bool achievement of the C++ standard:
>When I change the parameter type from bool to int the code compiles
>without ambiguities (and selects the right function, what can be
>verified by commenting out it: the other isn't at all considered a
>candidate):
>
>--- start code ---
>#include <string>
>
>class foo
>{
> public:
> explicit foo( const std::string & pName, int pIsRequired );
> explicit foo( int pValue, const std::string & pName );
>}
>
>foo( false, "b" );
>--- end code ---
>
>This is a messy workaround although, since it doesn't solve the real
>problem (automatic conversion of bool to std::string) but changes an
>unrelated part exploiting the fact that char[] doesn't convert to int.
>Also, I have to declare the boolean parameters with another than their
>real (logical) type corrupting clarity and forcing unnecessary
>conversions from the bool value to the int parameter type and then
>back to the bool instance variable type (the latter happening in the
>initializer, not shown in the code).
You could also use an enum { FALSE, TRUE };=20
Enum automatically converts to int -- but not the other way. Almost
like bool, but IMHO a little better.
>This solves my overload problem. What I don't understand is why the
>standard forces me to do such messy things or, in other words, why the
>standard renders it's own achievements (the bool type) useless by
>making bool convert to *everything*. And, what could be the semantic
>content of (automatically!) converting a truth value to void pointer?!
>What could this pointer point to?
As I see it, the problem is a one-way problem. But this one-way is
enough to create additional problems. However, I don't see a way
around it (auf deutsch: "das Kind mit dem Bad auszusch=FCtten...", or in
English: "throwing the baby out with the bath water"...)
>What sense does a bool type make if it isn't *really* distinguishable
>from all other types? It seems less usable than the int it is aimed to
>replace! In my view, bool should be the dead end of a "one way road"
>meaning that the conversion chain ends there, and there is no way back
>(other than an explicit user defined conversion from bool *itself*).
>
>What do the standard gurus say about this?
>
>Best Regards,
>Hartmut Sch=E4fer
><<-- end of text of posting to comp.std-c++ -->>
--
Bob Hairgrove
NoSpamPlease@Home.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hartmut.schaefer@techemail.com (Hartmut Sch?fer)
Date: Mon, 10 Jan 2005 18:28:57 GMT Raw View
Hello, all,
please consider the following code:
--- begin code ---
#include <string>
class foo
{
public:
explicit foo( const std::string & pName, bool pIsRequired );
explicit foo( bool pValue, const std::string & pName );
}
foo( false, "b" );
--- end code ---
I would expect the second form to win the overload resolution since
parameter 1 goes without conversion and parameter 2 needs a user
defined conversion, while the first form too needs a user defined
conversion (this time for the first parameter) and *additionally* a
standard conversion (for the second parameter).
Alas, the compilers I tried (IBM Visual Age 5.0 and 6.0 on AIX and Sun
Workshop PRO 5.0 on Solaris) don't see this so. This is what Visual
Age reports:
--- start output ---
(S) The call to "foo::foo" has no best match.
(I) Argument number 1 is an rvalue of type "bool".
(I) Argument number 2 is an lvalue of type "const char [2]".
(I) No candidate is better than "foo::foo(bool, const string &)".
(I) The conversion from argument number 1 to "bool" uses
"the identity conversion".
(I) The conversion from argument number 2 to "const
std::basic_string<char,std::char_traits<char>,std::allocator<char> >
&" uses
""an array-to-pointer transformation"" followed by
the user-defined conversion "std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char>
>::basic_string(const char *)" followed by
"an lvalue-to-rvalue transformation".
(I) No candidate is better than "foo::foo(const string &, bool)".
(I) The conversion from argument number 1 to "const
std::basic_string<char,std::char_traits<char>,std::allocator<char> >
&" uses
""a pointer conversion"" followed by
the user-defined conversion "std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char>
>::basic_string(const char *)" followed by
"an lvalue-to-rvalue transformation".
(I) The conversion from argument number 2 to "bool" uses
"an array-to-pointer transformation" followed by
"a boolean conversion".
--- end output ---
I can't see how the compiler should be able to apply a *pointer
conversion* to bool when the standard mentions only null pointer
constants and pointers to ... (4.10 [conv.ptr]) without first
converting bool to a pointer what I didn't find defined in the
standard at all. I would find it questionable, BTW..
Anyway, also accepting this, there are clear differences in the two
alternatives. As I understand the standard, the presence of a user
defined conversion makes the entire conversion sequence a user defined
conversion. We have one of them in both cases. The other conversion
sequence is in one case the identity conversion (that is no
concersion) and in the other a standard conversion. Since I would
consider no conversion to be better than a standard conversion, this
case should win.
This would also be what common sense dictates. It seems that the
standard doesn't see it this way. As a result, it is impossible to
overload functions in an obvious way. Why isn't bool simply a type
that cannot automatically (that is, not using user defined conversion
*from type bool*) be converted into *anything* else?
Regards,
Hartmut Sch fer
Z rcher Kantonalbank - Switzerland
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: invalid@bigfoot.com (Bob Hairgrove)
Date: Mon, 10 Jan 2005 20:21:24 GMT Raw View
On Mon, 10 Jan 2005 18:28:57 GMT, hartmut.schaefer@techemail.com
(Hartmut Sch=E4fer) wrote:
>#include <string>
>
>class foo
>{
> public:
> explicit foo( const std::string & pName, bool pIsRequired );
> explicit foo( bool pValue, const std::string & pName );
>}
>
>foo( false, "b" );
Hmm ... explicit is only effective with single-argument constructors,
or constructors where all but the first parameter take default
arguments. Otherwise, it is ignored. But that is irrelevant here.
(FWIW, the Comeau compiler agrees with the other ones. :( Here is the
output):
"E:\projects\cpp\scratch\conv.cpp", line 10: error: more than one
instance of
constructor "foo::foo" matches the argument list:
function "foo::foo(const std::string &, bool)"
function "foo::foo(bool, const std::string &)"
argument types are: (bool, const char [2])
foo( false, "b" );
^
One problem with implicit converting of bool is this -- how many times
have you seen or written something like this:
Object * pObj =3D Factory::getObject(...);
if (pObj)
{ /* do something with pObj*/ }
We *need* to have implicit conversion to bool for all pointer types,
at least for backwards-compatibility.
But you have a point. I can't see how the constructor of std::string
should be able to take "false" as an argument, because two conversions
are involved (albeit one implicit, the other user-defined). But I can
write:
#include <string>
class foo
{
public:
foo(bool pValue);
foo(const std::string & pName);
}
Both foo("b"); and foo(false); compile equally well here. Obviously,
the compiler has no trouble disambiguating the two. Note that I have
also left off the "explicit" keyword -- although here it might have
made sense!
Looks like it's time for the experts now.
--
Bob Hairgrove
NoSpamPlease@Home.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: bop@gmb.dk ("Bo Persson")
Date: Mon, 10 Jan 2005 21:12:15 GMT Raw View
"Bob Hairgrove" <invalid@bigfoot.com> skrev i meddelandet
news:2fn5u05940gp26ofqoctsioqi8vglr24jl@4ax.com...
On Mon, 10 Jan 2005 18:28:57 GMT, hartmut.schaefer@techemail.com
(Hartmut Sch fer) wrote:
>>#include <string>
>>
>>class foo
>>{
>> public:
>> explicit foo( const std::string & pName, bool pIsRequired );
>> explicit foo( bool pValue, const std::string & pName );
>>}
>>
>>foo( false, "b" );
<snip>
>But you have a point. I can't see how the constructor of std::string
>should be able to take "false" as an argument, because two conversions
>are involved (albeit one implicit, the other user-defined).
But false is a valid null pointer constant (4.10) that can be used by
the std::string(const char*) constructor. Undefined behavior, but of the
"no diagnostics required" kind...
Bo Persson
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]