3

我正在boost::any为教育目的制作一个简单的类,但我不知道如何访问存储的值。我可以完美地设置该值,但是当我尝试访问“持有人”类中的任何成员时,编译器只会抱怨在它派生的类中找不到该成员。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."
    }
};
4

2 回答 2

5

向模板添加虚函数很好——只是函数本身不能是模板。模板化的类或结构仍然可以很好地具有虚函数。您需要使用 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 更改为返回 a Datatype*,您可以返回NULL而不是抛出。您还没有处理 的先前值的内存StoredValue,但我将其留给您。

于 2011-02-15T13:59:47.133 回答
2

您需要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;
    }
于 2011-02-15T13:46:51.267 回答