lundi 16 novembre 2020

copy construct a vector of objects of an abstract class that is implemented by a template class

I have an abstract class say A which is implemented by a template class say B, B is specialized for a vector type that implements a copy constructor and a copy assignment operator, but when I compile i get the error: static assertion failed: result type must be constructible from value type of input range. Declaring a virtual copy assignment in the abstract class does not help, as the signature there is: A & operator=(const A &); but in B it is implemented for type B so the signatures do not match.

Why I have this weird hierarchy? Because I am trying to implement a json parsing library, I need to have a container that can store string, number, bigint, boolean and array types, so I implemented the hierarchy to achieve type erasure, the template type is for these 5 types and need to specialize only for string and vector types.

Actual hierarchy:

    class _BasicJsonType {
    public:
        virtual std::string toString() const = 0;
        virtual void setNull() = 0;
        // copy assignment method
        virtual _BasicJsonType& operator= (const _BasicJsonType &value) = 0;
        ~_BasicJsonType() = default;
    };

    template<typename T>
    class _BasicJsonTypeInterface: public _BasicJsonType {
    protected:
        bool __empty = true;

    public:
        virtual const T& get() const = 0;
        virtual void set(const T&) = 0;
    };

I created the interface type since I wanted to implement the get, set methods for all the types and irrespective of the type.

Array Specialization:

// json::array is defined as
using array = std::vector<_BasicJsonType>;

template<>
    class JsonValue<json::array>: public _BasicJsonTypeInterface<json::array> {
        std::shared_ptr<json::array> __array;
        bool __empty = true;

    public:
        JsonValue() = delete;

        JsonValue(const JsonValue<json::array> &value): JsonValue(*(value.__array)) {
            std::cout << "const JsonValue<json::array> &";
        }

        JsonValue(const json::array &array) {
            std::cout << "const json::array &";
            // error
            this->__array.reset(new json::array(array));
        }

        JsonValue(JsonValue<json::array> &&value): JsonValue(static_cast<json::array &&> (*(value.__array)))
        { std::cout << "const JsonValue<json::array> &"; }

        JsonValue(json::array &&array) {
            this->__array.reset(new json::array(std::move(array)));
            this->__empty = false;
        }
    };

I searched for the error, and what I found is I am missing a copy function for the _BasicJsonType, like what it suggests here.

There maybe some design flaws in this, since it is my first try with anything of practical use with c++, I am targeting for c++11.

Aucun commentaire:

Enregistrer un commentaire