The problem with std.conv.emplace

Timon Gehr timon.gehr at gmx.ch
Tue Oct 4 05:20:47 PDT 2011


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?



More information about the Digitalmars-d mailing list