Accessing values ​​in a class Like boost :: any

I am making a simple-like boost::anyclass for educational purposes, but I cannot figure out how to access the stored value. I can set the value perfectly, but when I try to access any member in the owner class, the compiler simply complains that the element was not found in the class from which it was obtained. I cannot declare items as virtualdue to patterns.

Here is the relevant code:

class Element
{
    struct ValueStorageBase
    {
    };

    template <typename Datatype>
    struct ValueStorage: public ValueStorageBase
    {
        Datatype Value;

        ValueStorage(Datatype InitialValue)
        {
            Value = InitialValue;
        }
    };

    ValueStorageBase* StoredValue;

public:

    template <typename Datatype>
    Element(Datatype InitialValue)
    {
        StoredValue = new ValueStorage<Datatype>(InitialValue);
    }

    template <typename Datatype>
    Datatype Get()
    {
        return StoredValue->Value; // Error: "struct Element::ValueStorageBase" has no member named "Value."
    }
};
+3
source share
2 answers

It’s great to add virtual functions to templates - only functions themselves cannot be templates. A template class or structure can still have virtual functions. You need to use dynamic_cast magic.

class Element
{
    struct ValueStorageBase
    {
        virtual ~ValueStorageBase() {}
    };

    template <typename Datatype>
    struct ValueStorage: public ValueStorageBase
    {
        Datatype Value;

        ValueStorage(Datatype InitialValue)
        {
            Value = InitialValue;
        }
    };

    ValueStorageBase* StoredValue;

public:

    template <typename Datatype>
    Element(Datatype InitialValue)
    {
        StoredValue = new ValueStorage<Datatype>(InitialValue);
    }

    template <typename Datatype>
    Datatype Get()
    {
        if(ValueStorage<DataType>* ptr = dynamic_cast<ValueStorage<DataType>*>(StoredValue)) {
            return ptr->Value;
        else
            throw std::runtime_error("Incorrect type!"); // Error: "struct Element::ValueStorageBase" has no member named "Value."
    }
};

Get, a Datatype*, NULL . StoredValue, .

+5

ValueStorage. ValueStorageBase, . , :).

:

template <typename Datatype>
    Datatype Element_cast()
    {
        //throw exception for a wrong cast
        if(typeid(*StoredValue)!=typeid(ValueStorage<Datatype>) )
               throw exception;

        //we already checked, that our type casting is OK,
        //So no need for dynamic_cast anymore
        return static_cast<ValueStorage*> (StoredValue)->value;
    }
+2

Source: https://habr.com/ru/post/1792228/


All Articles