任何铸造

时间:2010-06-19 13:52:45

标签: c++ boost casting boost-any

我将一些类打包到带有任何类型值的ptr_map中。

class EventManager
{
   ptr_map<string, any> mSomeMap;
   public:
      typedef signals2::signal<void (int someSignature)> KeyEvent;
      EventManager()
      {
         mSomeMap["KeyPressed"] = new any(new KeyEvent());
      }
};

现在我想恢复任何信号对象。这是一个特殊功能:

template<typename EventType>
EventType *get(const string &signalName)
{
    try {
        return any_cast<EventType*>(mSomeMap[signalName]);
    } catch(bad_any_cast &e){}
}

你还记得,boost的信号是不可复制的,所以我只能存储指针,我的函数也应该返回指针。

现在样本用法:

evManager.get<EventManager::KeyEvent>("KeyPressed");

这里我遇到了段错误。我检查了 get 函数中每个对象的类型:

typeid(EventType).name()
→ N5boost8signals26signalIFvRN2sf5Event8KeyEventEENS0_19optional_last_valueIvEEiSt4lessIiENS_8functionIS6_EENSB_IFvRKNS0_10connectionES5_EEENS0_5mutexEEE

mSignalAssociation[signalName].type().name()
→ N10__cxxabiv119__pointer_type_infoE

有什么问题?与铸造一致的段错误。 任何对象应该是否包含插入类型?为什么它不想投。

1 个答案:

答案 0 :(得分:3)

ptr_map<string, any> mSomeMap;

...
    mSomeMap["KeyPressed"] = new any(new KeyEvent());

你意识到这里发生了什么吗?首先,动态创建KeyEvent对象,从而生成指针。然后这个指针被包装到一个any-object中,该对象也是动态创建的,它也会返回一个指针,然后该指针会被赋值隐式地包含在另一个任何对象中。

此外,要从任何对象中提取正确的值,您需要知道确切的类型。因此,例如,如果您将Derived - 指针打包到任意对象中,您将无法通过any_cast<Base*>访问它,因为Base*Derived*std::type_info对象boost::any用于跟踪类型的不同类型。 boost::any只是不知道如何将打包的Derived - 指针转换为您的Base指针。

是否有一个特殊的原因可以包含any中包含许多内容的对象 - 包括指向any的对象 - 对象?使用像ptr_map<KeyType,BaseType>这样的东西不是很有意义吗?你知道如果你把一个指针打包到一个你自己仍然需要删除它的任何对象,对吧?任何对象都不会为你做这件事。