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.