Как выбрать переменную-член с параметром типа? - PullRequest
3 голосов
/ 06 августа 2010

У меня есть объект кеша, который кеширует несколько различных типов объектов, как показано ниже:

class Cache
{
public:
    ObjectTable<ObjTypeA> m_objACache;
    ObjectTable<ObjTypeB> m_objBCache;
    ObjectTable<ObjTypeC> m_objCCache;
};

(Ужасный) способ, которым я сейчас использую кеш - прямой доступ кСвойства класса кэша "m_objACache" и "m_objBCache", например, так:

Cache c;
c.m_objACache.getObjectWithid(objectBuffer, 1);
c.m_objACache.getObjectWithid(objectBuffer, 2);
c.m_objBCache.getObjectWithid(objectBuffer, 3);

и т. д.

То, что я хотел бы сделать, это примерно так: -

class Cache
{
public:
    template <typename T>
    void getObjectWithId(T &objectBuffer, int id)
    {
        ObjectTable<T>.getObjectWithId(objectBuffer, id);
    }
};

Но очевидно, что это не работает, потому что там, где у меня есть "ObjectTable<T>", мне нужно имя переменной, но я не могу шаблонировать переменные класса - так есть ли способ, которым я могу это сделать?Или это будет так, если объявить все переменные и получить к ним доступ следующим образом:

class Cache
{
public:
    void getObjectWithId(ObjTypeA &objectBuffer, int id)
    {
        m_objACache.getObjectWithId(objectBuffer, id);
    }

    void getObjectWithId(ObjTypeB &objectBuffer, int id)
    {
        m_objBCache.getObjectWithId(objectBuffer, id);
    }

    void getObjectWithId(ObjTypeC &objectBuffer, int id)
    {
        m_objCCache.getObjectWithId(objectBuffer, id);
    }

protected:
    ObjectTable<ObjTypeA> m_objACache;
    ObjectTable<ObjTypeB> m_objBCache;
    ObjectTable<ObjTypeC> m_objCCache;
};

Что кажется очень многословным ..

Каждый тип объекта, который может использоваться в ObjectTablefor имеет общий базовый класс, так что может быть какой-то другой способ сделать это, который неизбежно может включать в себя уныние, но я надеюсь, что смогу найти лучший способ.

Спасибо!

Ответы [ 2 ]

7 голосов
/ 06 августа 2010

Как это возможно?

class Cache
{
 // An "envelope" type which up-casts to the right ObjectTable<T> 
 // if we have a type parameter T. 
 struct ObjectTables : ObjectTable<ObjTypeA>,  
                       ObjectTable<ObjTypeB>, 
                       ObjectTable<ObjTypeC> {};

 ObjectTables tables; 
public:

    template <typename T>
    void getObjectWithId(T &objectBuffer, int id)
    { 
        // C++ does the work here
        ObjectTable<T> &o=tables;
        t.getObjectWithId(objectBuffer, id);
    }
};

Кроме того, его легко расширить. Просто добавьте больше ObjectTables <>, если вам нужно поддерживать больше типов.

0 голосов
/ 06 августа 2010

Boost.Fusion имеет boost::fusion::map для этой цели.

Вы отображаете тип на другой тип, первый является чистой подсказкой компиляции, второй фактически создается.

Затем вы запрашиваете:

boost::fusion::map< std::pair<Key1,Value1> > map;
Value1& v = boost::fusion::at<Key1>(map);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...