
Eric Niebler wrote:
[...redefining NULL breaks things...] <>struct foo { foo(void*) {} }; void bar(foo f) {} void baz() { bar(NULL); }
Works with NULL as 0, fails with NULL as null because it needs two user-defined conversions.
Redefining NULL is a career-limiting move. Don't do it.
Alright, I concede that I shouldn't redefine a standard macro. :-P Interesting example by the way... hadn't thought of that. Would be nice if there was a way around it. I find the upper limit on user defined implicit conversions frustrating. This limit has already thwarted my plan to make a smart reference type which only locks the contained instance while being implicitly converted to the raw reference type. It would have worked something like: template < typename Type > struct Ref { struct InternalRef { Lock my_lock; operator Type & ( ); }; operator InternalRef ( ); }; This was planned to work similar to the locking pointer idiom: template < typename Type > struct Ptr { struct InternalPtr { Lock my_lock; Type * operator -> ( ); }; InternalPtr * operator -> ( ); }; But sadly, the locking reference idea requires two implicit user defined conversions. And I can't exactly overload the '.' operator. *sigh* Why does the C++ language have to ban such potentially fun things as infinite implicit conversion chains and overloading the dot operator? -Jason