Emplace using private constructor
Ali Çehreli
acehreli at yahoo.com
Fri Jun 7 09:14:24 PDT 2013
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
More information about the Digitalmars-d-learn
mailing list