как создать контейнер, который принимает по одному объекту каждого вида?

Я попытался создать контейнер для возможных метаданных, которые можно прикрепить к моим объектам. Я могу гарантировать, что к моему классу будет прикреплено не более одного объекта каждого типа, но нет ограничений на присоединение объектов разных типов. например, я не могу присоединить два экземпляра wordInfo к объекту, но экземпляры классов wordInfo и phraseInfo можно присоединить к объекту одновременно. вот что я сделал до сих пор, чтобы сделать это.

class object
{
    std::map <std::type_info, object*> mMetaData;
    public:
    inline void attachMetaData(object* pData)
    {
        mMetaData[typeid(*pData)] = pData;
    }
    template <class T> inline std::enableif<std::is_base_of<object,T>::value, T*>::type getMetaData()
    {
        if (mMetaData.find(typeid(T)) == mMetaData.end())
            return NULL;
        else
            return mMetaData[typeid(T)];
    }
    template <class T> inline std::enableif<std::is_base_of<object,T>::value, void>::type detachMetaData()
    {
        mMetaData.erase(typeid(T));
    }
}

в приведенном выше коде была ошибка компиляции: оператор less не был определен для std::type_info, поэтому я определил класс less специально для std::type_info и передал его в качестве третьего параметра шаблона класса карты следующим образом:

struct typeinfoless
{
    bool operator()(std::type_info& left, std::type_info& right)
    {
        return left.hash() < right.hash();
    }
}
std::map <std::type_info, object*, typeinfoless> mMetaData;

но затем я столкнулся с другой ошибкой, которую я не знаю, как решить, std::type_info имеет частный конструктор и даже частный конструктор копирования, поэтому я даже не могу получить от него какой-то класс. Любая идея, как я могу решить эту проблему? или любой другой возможный способ создать мой класс object?


person Ali1S232    schedule 20.06.2011    source источник
comment
также обсуждение в stackoverflow.com/questions/3552135/, вероятно, даже более подходит   -  person Cubbi    schedule 21.06.2011
comment
@cubbi: кажется, нет, у меня есть хэш-функция, которая была основным вопросом в том, что вы отметили. Я не уверен, что это реализация VC++ или что-то еще, но type_info имеет хэш-функцию, и я могу легко ее использовать, моя проблема заключается в создании класса карты с type_info в качестве ключа, потому что я получил ошибку type_info::type_info недоступен.   -  person Ali1S232    schedule 21.06.2011
comment
@cubbi: а что касается вашего первого предложения, кажется, я могу использовать его для решения своей проблемы, но оно не дает советов, как использовать стандартный объект std::type_info или typeid в C++, оно переопределяет сами объекты RTTI.   -  person Ali1S232    schedule 21.06.2011
comment
@cubbi: у typeid есть одна большая особенность по сравнению с ответами в вашем первом обсуждении: вы можете вызывать typeid(int) и int i; typeid(i), и они оба возвращают одно и то же. который я не знаю, как сгенерировать, используя ответ там.   -  person Ali1S232    schedule 21.06.2011


Ответы (2)


Создайте класс-оболочку для std::type_info, подобный следующему:

class TypeWrapper
{
    private const std::type_info &mInfo;
    public TypeWrapper(const std::type_info &info) : mInfo(info)
    {
    }
    // Functions required by a key into a std::map.
};

Используйте TypeWrapper в качестве ключа к вашей карте.

person TreDubZedd    schedule 20.06.2011
comment
кажется, что возвращаемое значение typeid не std::type_info и не std::type_info&. поэтому я не могу позвонить TypeWrapper(typeid(int)) - person Ali1S232; 21.06.2011

Извиняюсь за ответ на древний вопрос, но это был первый результат в гугле, когда я пытался разобраться. Вместо создания класса-оболочки вы должны использовать класс-оболочку std::type_index в качестве ключа к вашей карте.

person andreasm    schedule 06.10.2012