The problem with std.conv.emplace

Benjamin Thaut code at benjamin-thaut.de
Mon Oct 3 23:05:41 PDT 2011


I'm currently trying to fix the problem I have with std.conv.emplace to 
fully replace the deprecated new/delete operator overloading with a 
template.
However it discovered that this is currently not possible, at least not 
to my knowdelge. The problem is as follows:

class Foo {
}

class Test {
   private:
     Foo m_foo;
   public:
     this(Foo foo){
       m_foo = foo;
     }

     void SetFoo(Foo foo){
       m_foo = foo;
     }
}

void main(){
   void[__traits(classInstanceSize,Test)] mem = typeid(Test).init[];
   emplace!Test(mem,null); //do not know how to create a object of type 
test with args (void*)
}

If I however do the following it works (ignore the missing init part here):
void main(){
   void[__traits(classInstanceSize,Test)] mem = typeid(Test).init[];
   Test t = cast(Test)mem.ptr;
   t.__ctor(null);
}

The same problem occurs when you do:
void CallSetFoo(T)(Test c,T arg){
   c.SetFoo(arg);
}

CallSetFoo(new Test(),null);

It seems that null actually has it's own type but that type is not 
exposed into the language and is lost as soon as null is passed to a 
template. To a template null just looks like a void* and therefore can 
not be used correctly any more.

Now one could write some code that would query all possible constructors 
find a matching one and manually cast void* to the correct reference 
type however this would require a runtime check for null to avoid 
casting any void* to a reference, and I would highly prefer a solution 
that would not require runtime checks to be safe.

My suggestion would be to actually give null it's own type and expose 
that into the language so it can be correctly used with templates.

Any other ideas how to fix this? Maybe there is a way with the current 
type system I don't know of.

-- 
Kind Regards
Benjamin Thaut


More information about the Digitalmars-d mailing list