The problem with std.conv.emplace

kennytm kennytm at gmail.com
Tue Oct 4 11:44:43 PDT 2011


Timon Gehr <timon.gehr at gmx.ch> wrote:
> On 04.10.2011 08:05, Benjamin Thaut wrote:
>> 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.
>> 
> This works.
> 
> emplace!Test(mem,cast(Foo)null);
> 
> But I am totally supporting your suggestion. null should not decay to a
> void* on template argument boundaries, it has bugged me multiple times.
> 
> Is there already an enhancement request/bug report for this?

I did mention nullptr_t in 5899 <g>.


More information about the Digitalmars-d mailing list