mercredi 27 mai 2015

Constructor and copy-constructor for class containing union with non-trivial members

I am trying to implement a custom variant type which uses a union to store data of various different types. In the field type_id I plan to store which type the data stored in the union is of. The union contains non-trivial members. Here is my current implementation:

struct MyVariant {
  enum { t_invalid, t_string, t_int, t_double, t_ptr, t_dictionary } type_id;
  union {
    int                             as_int;
    double                          as_double;
    std::string                     as_string;
    std::unique_ptr<int>            as_ptr;
    std::map<int, double>           as_dictionary;
  };
};

I try to create an instance of MyVariant like follows:

MyVariant v;

I get the error message: Call to implicitly-deleted default constructor of MyVariant. So, I tried to implement the constructor manually like follows:

MyVariant() : type_id{t_int}, as_int{0} {}

That gives me a similar error message: Attempt to use a deleted function. Next, I tried to implement the following constructor:

MyVariant(int value) : type_id{t_int}, as_int{value} {}

and construct my instance like follows:

MyVariant v{123};

=> same error message: Attempt to use a deleted function.

I've also started to implement a copy constructor, it looks like follows. However, of course this doesn't help with the compiler errors.

MyVariant::MyVariant(const MyVariant& other)
{
    type_id = other.type_id;
    switch (type_id) {
        case t_invalid:
            break;
        case t_string:
            new (&as_string) std::string();
            as_string = other.as_string;
            break;
        case t_int:
            as_int = other.as_int;
            break;
        case t_double:
            as_double = other.as_double;
            break;
        case t_ptr:
            new (&as_ptr) std::unique_ptr<int>(nullptr);
            as_ptr = std::make_unique<int>(*other.as_ptr);
            break;
        case t_dictionary:
            new (&as_dictionary) std::map<int, double>();
            // TODO: copy values from other
            break;
    }
}

I am using Xcode and Apple LLVM 6.1 as compiler.

The main question is: Why do I get the compiler errors which I'm getting and how do I have to modify my code to make it compile?

The additional question is: Am I on the right way with my implementations for the constructor and copy constructor?

Aucun commentaire:

Enregistrer un commentaire