我正在制作一个简单的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."
}
};
答案 0 :(得分: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."
}
};
如果您更改获取以返回Datatype*
,则可以返回NULL
而不是投掷。您还没有处理StoredValue
之前值的记忆,但我将其留给您。
答案 1 :(得分: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;
}