Denis Koroskin wrote:
On Thu, 04 Jun 2009 22:10:58 +0400, Andrei Alexandrescu <[email protected]> wrote:

Max Samukha wrote:
On Thu, 04 Jun 2009 10:41:31 -0500, Andrei Alexandrescu
<[email protected]> wrote:

You are mistakenly presupposing that if() takes a bool. In reality if() accepts a bool, an integral, a floating-point type, a pointer, an array, or a class reference.
 or delegate

I was sure I forgot something... and hash too. Anything that can be compared against 0 or null.

Andrei

Is it considered a good practice?

Technically, the following construct is not exactly portable:

float f = ..;
if (f) {
}

because C (nor D) standard doesn't guaranty that float(0) will be implemented as "all bits set to 0" on target platform (although it currently holds true).

That _is_ guaranteed. Even on not-quite-conformant systems.
Actually, -0.0 is not implemented as "all-bits-zero", yet this works:
void main(){
   float f = -0.0;
   if (f) assert(0);
}
There's no portability problem here.

To fix the original issue, we'd just need to allow something like:

struct S
{
   bool opEquals(int x) { return (x!=0); }
}

void main()
{
   S x;
   if (x) assert(0);
}

That is, if x is a struct, convert "if(x)" into "if(x==0)"
and convert "if(!x)" into "if(x!=0)". Usual rules would then apply, so any opEquals with a parameter which could be implicitly cast from 0 would work.

That wouldn't allow smart-pointer structs to implement if (x) without requiring them to allow comparisons with integers, so it might be necessary to add a second step: try "if(x==null)" instead.

Alternatively, introduce a "bool opNull()" member function for structs.
Both solutions are easy to implement.

Reply via email to