Доступ к значениям в классе, аналогичном boost :: any - PullRequest
3 голосов
/ 15 февраля 2011

Я делаю простой boost::any подобный класс для образовательных целей, но я не могу понять, как получить доступ к сохраненному значению. Я могу точно установить значение, но когда я пытаюсь получить доступ к любому члену в классе "holder", компилятор просто жалуется, что член не был найден в классе, из которого он был получен. Я не могу объявить участников как virtual из-за шаблонов.

Вот соответствующий код:

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."
    }
};

Ответы [ 2 ]

5 голосов
/ 15 февраля 2011

Хорошо добавлять виртуальные функции в шаблоны - только сами функции не могут быть шаблонами.У шаблонного класса или структуры все еще могут быть виртуальные функции.Вам нужно использовать магию dynamic_cast.

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 для возврата Datatype*, вы можете вернуть NULL вместо броска.Вы также не обработали память предыдущего значения StoredValue, но я оставляю это на ваше усмотрение.

2 голосов
/ 15 февраля 2011

Сначала вам нужно привести его к ValueStorage.Также добавьте виртуальный деструктор в класс ValueStorageBase, чтобы иметь полиморфный класс.Без него вы не сможете проверить во время исполнения, в порядке ли ваше приведение :)

...