Donate. I desperately need donations to survive due to my health

Get paid by answering surveys Click here

Click here to donate

Remote/Work from Home jobs

c++ - Is it possible to deal with union member in a class without a flag to keep track of which variable in the union to be used?

I have a derived class which has a union member of itself, where the union stores two smart pointers. However, when I try to copy-initialize some instances of this class, the compiler report an error that I'm referring to a deleted function. So I guess it's because it has a union variable and thus the compiler cannot generate a default copy constructor for the class.

class declaration:

struct EndpointInfo : public IntersectInfo {
        EndpointInfo() {}
        EndpointInfo(const EndpointInfo &other) : _emitter(other._emitter),  {}

        EndpointInfo(const std::shared_ptr<ProjectiveSensor> s, const Ray &ray) : IntersectInfo(ray._o), _sensor(s) {}
        EndpointInfo(const std::shared_ptr<Emitter> e, const Ray &ray, const Vec3f &n_light) : IntersectInfo(ray._o), _emitter(e) {
            _normal = n_light; // _normal is a member of base class.
        }
        ~EndpointInfo() {}

        union {
            const std::shared_ptr<ProjectiveSensor> _sensor;
            const std::shared_ptr<Emitter> _emitter;
        };
    };

In case the base class declaration is needed:

struct IntersectInfo {
    Point3f _p;
    Vec3f _wo;
    float _t = INFINITY;
    Vec3f _normal;
    TransportMode _transport_mode;

    std::shared_ptr<Primitive> _primitive;
    std::shared_ptr<BSDF> _bsdf;
    struct {
        Vec3f _n;
        Vec3f _tangent;
        Vec3f _bitangent;
    } _shading;
    Vec3f _dpdu, _dpdv;

    IntersectInfo() = default;
    IntersectInfo(const IntersectInfo &origin);
    IntersectInfo(const Point3f p);

};

So from the above code, the base class IntersectInfo already possesses a copy constructor, and I think all I care about is how to copy the union in the copy constructor of EndpointInfo.

My question is, after I read this thread, I was thinking if I can use something like memcpy, which doesn't care about the actual type, but just how much memory it copies. And since only std::shared_ptrs are in the union, and no matter which one, _sensor or _emitter I want to copy to (which are of same memory size), I just copy a chunk of memory. If I could, can I use:

EndpointInfo(const EndpointInfo &other) : _emitter(other._emitter),  {
    // either
    memcpy(&_sensor, &other._sensor, sizeof(_sensor));
    // or
    memcpy(&_emitter, &other._emitter, sizeof(_emitter));
    // even
    _sensor = other._sensor;
}

If I cannot use like that, is there other way rather than explicitly use a variable to specify the type?

Comments