D using emplace

74 Views Asked by At

I am trying to use emplace in this piece of code:

class motionFactory{
        public:
            this(double velocity, double gravity, double angle){
                this.velocity = velocity;
                this.gravity = gravity;
                this.angle = angle;
            }
            motion getMotion(double step) const{
                auto ptr = malloc(motion.sizeof);
                return emplace!motion(ptr, velocity, gravity, angle, step);
            }
        private:
            double velocity;
            double gravity;
            double angle;
    }

    class motion : motionFactory{
        public:
            this(double velocity, double gravity, double angle, double step){
                super(velocity, gravity, angle);
                this.current = 0;
                this.step = step;
                this.range = getCurrentRange();
            }
        private:
            double current;
            const double step;
            const double range;

    }

And I keep getting this singular compilation error.

error: template std.conv.emplace cannot deduce function from argument types !(motion)(motion, const(double), const(double), const(double), double), candidates are:
  102 |                 return emplace!motion(ptr, velocity, gravity, angle, step);

After looking at the documentation for too long with no avail, I'm at a loss. Please help

2

There are 2 best solutions below

0
TCA 166 On BEST ANSWER

I found the solution by tinkering with the examples on the doc page for emplace.

size_t size = __traits(classInstanceSize, motion);
void[] ptr = malloc(size)[0..size];
return emplace!motion(ptr, velocity, gravity, angle, step);

This compiles and works just fine for me. Fascinatingly enough keeping the cast there meant the D allocator would get called somewhere which would opens the door to allocator mixing.

2
Steven Schveighoffer On

emplace takes as the first parameter not an untyped pointer, but a pointer typed as the thing to be emplaced.

That is one problem. The second problem is that motion.sizeof is going to be the size of the class reference, in other words, the size of a pointer. You want the size of the class data. To get this, you want to use __traits(classInstanceSize, motion).

The getMotion function should be changed to:

            motion getMotion(double step) const{
                auto ptr = cast(motion)malloc(__traits(classInstanceSize, motion));
                return emplace(ptr, velocity, gravity, angle, step);
            }