如何使用类型参数选择成员变量?

时间:2010-08-06 08:28:39

标签: c++ design-patterns templates oop

我有一个缓存对象,可以缓存许多不同类型的对象,如下所示:

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;
};

这看起来非常冗长..

ObjectTable可用于的每个对象类型都有一个共同的基类,因此可能有其他一些方法可能会涉及向下转换,但我希望我能找到更好的方法。

谢谢!

2 个答案:

答案 0 :(得分:7)

或许这样吗?

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&lt;&gt;如果你需要支持更多类型。

答案 1 :(得分:0)

为此目的,Boost.Fusion有一个boost::fusion::map

您将类型映射到另一种类型,第一种是纯编译提示,第二种实际是实例化。

然后请求:

boost::fusion::map< std::pair<Key1,Value1> > map;
Value1& v = boost::fusion::at<Key1>(map);