vendredi 26 février 2016

Tagged Union with std::string does not work unless the union is anonymous [duplicate]

This question already has an answer here:

I asked a question about this before but I still do not see why two similar versions of the same code. When I make the union anonymous then it somehow seems to work. The code that compiles is the following

Code that compiles

class VariantType {
public:
    enum class InnerType {INTEGER, STRING};
    InnerType inner_type;

    union {
        int inner_int;
        string inner_string;
    };

    VariantType(InnerType type) : inner_type{type} {
        switch (this->inner_type) {
            case (InnerType::INTEGER) :
                new(&inner_int) int();
                break;
            case (InnerType::STRING) :
                new(&inner_string) string();
                break;
        }
    }

    ~VariantType() {
        if (this->inner_type == InnerType::STRING) {
            inner_string.~string();
        }
    }
};

Code that does not compile

class VariantType {
public:
    enum class InnerType {INTEGER, STRING};
    InnerType inner_type;

    union TypeUnion {
        int inner_int;
        string inner_string;
    } inner_union;

    VariantType(InnerType type) : inner_type{type} {
        switch (this->inner_type) {
            case (InnerType::INTEGER) :
                new(&this->inner_union.inner_int) int();
                break;
            case (InnerType::STRING) :
                new(&this->inner_union.inner_string) string();
                break;
        }
    }

    ~VariantType() {
        if (this->inner_type == InnerType::STRING) {
            this->inner_union.inner_string.~string();
        }
    }
};

This does not compile with the following errors

some.cpp:104:5: error: call to implicitly-deleted default constructor of 'union TypeUnion'
    VariantType(InnerType type) : inner_type{type} {
    ^
some.cpp:101:16: note: default constructor of 'TypeUnion' is implicitly deleted because variant field 'inner_string' has a non-trivial default constructor
        string inner_string;
               ^
some.cpp:104:5: error: attempt to use a deleted function
    VariantType(InnerType type) : inner_type{type} {
    ^
some.cpp:101:16: note: destructor of 'TypeUnion' is implicitly deleted because variant field 'inner_string' has a non-trivial destructor
        string inner_string;
               ^
some.cpp:115:5: error: attempt to use a deleted function
    ~VariantType() {
    ^
some.cpp:101:16: note: destructor of 'TypeUnion' is implicitly deleted because variant field 'inner_string' has a non-trivial destructor
        string inner_string;
               ^
3 errors generated.

And I am compiling code with the following command

g++ -std=c++14 -c some.cpp

Aucun commentaire:

Enregistrer un commentaire