Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
August 16, 2013 Implicit conversion to bool, and other conversions. | ||||
---|---|---|---|---|
| ||||
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)? |
August 16, 2013 Re: Implicit conversion to bool, and other conversions. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carl Sturtivant | 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 |
August 16, 2013 Re: Implicit conversion to bool, and other conversions. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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 |
August 16, 2013 Re: Implicit conversion to bool, and other conversions. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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
|
August 16, 2013 Re: Implicit conversion to bool, and other conversions. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carl Sturtivant | 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
|
August 16, 2013 Re: Implicit conversion to bool, and other conversions. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis: > I'd advise against that, Related: http://d.puremagic.com/issues/show_bug.cgi?id=3926 Bye, bearophile |
August 17, 2013 Re: Implicit conversion to bool, and other conversions. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | 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. |
August 17, 2013 Re: Implicit conversion to bool, and other conversions. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | 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.
|
Copyright © 1999-2021 by the D Language Foundation