www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Implicit conversion to bool, and other conversions.

reply "Carl Sturtivant" <sturtivant gmail.com> writes:
The operator overloading page in the Language Reference and the 
operator overloading discussion in TDLP say different things about
   T opCast(bool)() if(is(T==bool))
and experimentally it seems that in any context where a bool is 
expected and x occurs (where x is a struct with such an opCast 
defined) then x will be rewritten as its conversion to bool using 
that opCast.

Please confirm that the above is generally true or tell me the 
exact rules.

Are there any other implicit conversions possible in D (apart 
from int to long, int to double and so forth)?
Aug 16 2013
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/16/2013 02:18 PM, Carl Sturtivant wrote:

 The operator overloading page in the Language Reference and the operator
 overloading discussion in TDLP say different things about
    T opCast(bool)() if(is(T==bool))
The current syntax is the following: bool opCast(T : bool)() const
 and experimentally it seems that in any context where a bool is expected
 and x occurs (where x is a struct with such an opCast defined) then x
 will be rewritten as its conversion to bool using that opCast.
As far as I know, opCast in general is for explicit type conversions, not explicit. However, bool is special: certain language constructs (e.g. assert, if, etc.) will make an explicit conversion to bool even when the program does not ask for one. For example, the last line does not compile because opCast is not used for converting from S to bool: struct S { int i; bool opCast(T : bool)() const { return i == 42; } } void main() { auto s_true = S(42); auto s_false = S(43); assert(s_true); assert(!s_false); bool b = s_true; // compilation ERROR }
 Please confirm that the above is generally true or tell me the exact 
rules.
 Are there any other implicit conversions possible in D (apart from int
 to long, int to double and so forth)?
I know 'alias this' is for implicit conversions. Ali
Aug 16 2013
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/16/2013 02:35 PM, Ali Çehreli wrote:

 As far as I know, opCast in general is for explicit type conversions,
 not explicit.
Ha! Should be: ... is for explicit type conversions, not *implicit*. Ali
Aug 16 2013
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, August 16, 2013 14:35:53 Ali Çehreli wrote:
 On 08/16/2013 02:18 PM, Carl Sturtivant wrote:
 The operator overloading page in the Language Reference and the operator
 overloading discussion in TDLP say different things about
 
 T opCast(bool)() if(is(T==bool))
The current syntax is the following: bool opCast(T : bool)() const
I'd advise against that, as what that's doing is overloading opCast for any type which implicitly converts to bool rather than just bool. Depending on the situation, that might be fine, but in general, you need to be very careful with implicit conversions - especially when generic code is involved. It's far too easy to end up with templated code that tries to instantiate with types that it doesn't work with. - Jonathan M Davis
Aug 16 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 I'd advise against that,
Related: http://d.puremagic.com/issues/show_bug.cgi?id=3926 Bye, bearophile
Aug 16 2013
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, August 16, 2013 23:18:51 Carl Sturtivant wrote:
 The operator overloading page in the Language Reference and the
 operator overloading discussion in TDLP say different things about
 T opCast(bool)() if(is(T==bool))
 and experimentally it seems that in any context where a bool is
 expected and x occurs (where x is a struct with such an opCast
 defined) then x will be rewritten as its conversion to bool using
 that opCast.
 
 Please confirm that the above is generally true or tell me the
 exact rules.
 
 Are there any other implicit conversions possible in D (apart
 from int to long, int to double and so forth)?
opCast is only ever for explicit conversions. alias this is used for implicit conversions. Whether things get confusing is that there are places where the compiler inserts casts for you, so it _looks_ like there's an implicit conversion, but there isn't really. In particular, cast(bool) is inserted in the conditions of if statements, loops, ternary operators, and assertions. So, if you have something like if(a) {} it becomes if(cast(bool)a) {} So, if you want to use a struct in a condition, you overload opCast for bool, but if you want it to implicitly convert to bool in general, then you use alias this. - Jonathan M Davis
Aug 16 2013
next sibling parent "Carl Sturtivant" <sturtivant gmail.com> writes:
On Friday, 16 August 2013 at 22:11:24 UTC, Jonathan M Davis wrote:
 On Friday, August 16, 2013 23:18:51 Carl Sturtivant wrote:
 The operator overloading page in the Language Reference and the
 operator overloading discussion in TDLP say different things 
 about
 T opCast(bool)() if(is(T==bool))
 and experimentally it seems that in any context where a bool is
 expected and x occurs (where x is a struct with such an opCast
 defined) then x will be rewritten as its conversion to bool 
 using
 that opCast.
 
 Please confirm that the above is generally true or tell me the
 exact rules.
 
 Are there any other implicit conversions possible in D (apart
 from int to long, int to double and so forth)?
opCast is only ever for explicit conversions. alias this is used for implicit conversions. Whether things get confusing is that there are places where the compiler inserts casts for you, so it _looks_ like there's an implicit conversion, but there isn't really. In particular, cast(bool) is inserted in the conditions of if statements, loops, ternary operators, and assertions. So, if you have something like if(a) {} it becomes if(cast(bool)a) {} So, if you want to use a struct in a condition, you overload opCast for bool, but if you want it to implicitly convert to bool in general, then you use alias this.
The conversion to bool via opCast seems more general than that: the following compiles and runs. void main() { A x; if( x && f(99)) writeln( "yes!"); bool b = f(201) && x; writeln( b); } struct A { bool opCast(T)() if( is( T==bool)) { return true; } } bool f(int x) { return x%2 == 1; } And the online docs here http://dlang.org/operatoroverloading.html#Cast say "etc., whenever a bool result is expected". So that seems likely to happen in arbitrary logical expressions, in fact in any context where a bool is expected perhaps.
Aug 16 2013
prev sibling parent "Carl Sturtivant" <sturtivant gmail.com> writes:
On Friday, 16 August 2013 at 22:11:24 UTC, Jonathan M Davis wrote:
 On Friday, August 16, 2013 23:18:51 Carl Sturtivant wrote:
 The operator overloading page in the Language Reference and the
 operator overloading discussion in TDLP say different things 
 about
 T opCast(bool)() if(is(T==bool))
 and experimentally it seems that in any context where a bool is
 expected and x occurs (where x is a struct with such an opCast
 defined) then x will be rewritten as its conversion to bool 
 using
 that opCast.
 
 Please confirm that the above is generally true or tell me the
 exact rules.
 
 Are there any other implicit conversions possible in D (apart
 from int to long, int to double and so forth)?
opCast is only ever for explicit conversions. alias this is used for implicit conversions. Whether things get confusing is that there are places where the compiler inserts casts for you, so it _looks_ like there's an implicit conversion, but there isn't really. In particular, cast(bool) is inserted in the conditions of if statements, loops, ternary operators, and assertions. So, if you have something like if(a) {} it becomes if(cast(bool)a) {} So, if you want to use a struct in a condition, you overload opCast for bool, but if you want it to implicitly convert to bool in general, then you use alias this. - Jonathan M Davis
I hadn't fully understood alias this, i.e. that one may alias what becomes effectively a conversion function of no arguments. Thank you for pointing me in that direction.
Aug 16 2013