【问题标题】:How do I select a member variable with a type parameter?如何选择带有类型参数的成员变量?
【发布时间】:2011-03-26 05:25:48
【问题描述】:

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

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&lt;T&gt;”我需要一个变量名,但我不能模板类变量 - 那么有没有办法可以做到这一点?或者,如果声明所有变量并像这样访问它,会不会是这样:

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 可用于的每个对象类型都有一个公共基类,因此可能有其他一些方法可以做到这一点,这可能不可避免地涉及向下转换,但我希望我能找到更好的方法。

谢谢!

【问题讨论】:

    标签: c++ design-patterns templates oop


    【解决方案1】:

    也许像这样?

    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。

    【讨论】:

    • 对于通用版本不够好的少数例外情况,甚至可以添加 getObjectWithId() 的显式特化。
    • 这真是太美了。
    • 非常漂亮的图案。 @Nordic,隐式 static_cast 开销很大吗?
    【解决方案2】:

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

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

    然后你请求:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-11
      • 2020-09-29
      • 2021-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多