tldr; I had the crazy idea of mixing-in a specialization of emplace but failed probably because mixin does not respect template constraints.

On 06/07/2013 06:50 AM, develop32 wrote:

> Nevermind, problem was not worth the question. I just copied code from
> Phobos std.conv.emplace and placed it directly in my code, it works
> since it is in the same module as the private constructor.

But it is too heavy-handed. Your problem exposes a real weakness. Other library code will make assumptions like emplace does below and they will fail if the constructor is not accessible. From std.conv.emplace:

    // Call the ctor if any
    static if (is(typeof(result.__ctor(args))))
    {
        // T defines a genuine constructor accepting args
        // Go the classic route: write .init first, then call ctor
        result.__ctor(args);
    }

I tried making your code better but not copying emplace's implementation:

module display;

import std.conv;

class Display
{
private:
    const string name;

    this(string name)
    {
        this.name = name;
    }

public:

    static Display emplace(Args...)(void[] chunk, auto ref Args args)
    {
        return std.conv.emplace!(Display)(chunk, args);
    }
}

Here is a test program:

import display;

void main()
{
    enum roomNeeded = __traits(classInstanceSize, Display);
    ubyte[roomNeeded] buffer;
    auto d = Display.emplace(buffer, "hello");
}

But I failed with the same error:

Error: static assert "Don't know how to initialize an object of type Display with arguments (string)"

Then I thought about mixing in the template but that did not work either:

class Display
{
// ...

    static Display emplace(Args...)(void[] chunk, auto ref Args args)
    {
        mixin std.conv.emplace!(Display, string);
    }
}

The error message indicated that mixin was picking the wrong specialization, because it had a template constraint for 'struct':

T* emplace(T, Args...)(T* chunk, auto ref Args args)
    if (is(T == struct))
{
    // ...
}

If it picked the one that matched is(T == class) then we would have achieved our goal without copy-pasting.

Still, if it worked, it also feels hacky because we would be mixing-in a specialization right inside our function and hope that it would somehow work in our environment. For example, the specialization of emplace has a return statement:

    return result;

What if my function should not return? I guess then we would mix-in inside a wrapper function, call that function, and ignore the return value.

I have a feeling that bearophile already has a bug report about all of this but I haven't checked yet. :p

Not the same, but it look like it is related to this bug:

  http://d.puremagic.com/issues/show_bug.cgi?id=9235

Ali

Reply via email to