如何使用Traits模式访问类的不同成员

时间:2011-10-19 22:45:25

标签: c++ stl vector traits

我有一个包含几个对象向量的类:

struct ComponentA
{
 public:
   methodA1();
   float data1;
   ...
};
struct ComponentB
{
   ...
};
struct ComponentC
{
   ...
};
struct ComponentD
{
   ...
};

class Assembly
{
    vector<ComponentA> As;
    vector<ComponentB> Bs;
    vector<ComponentC> Cs;
    vector<ComponentD> Ds;
};

我想使用traits并定义一个可以返回对这样的成员的引用的函数:

template< int T >
struct ComponentTraits;

template<>
ComponentTraits<TYPEA>
{
    typedef vector<ComponentA> data_type;
}
....
template< int T >
ComponentTraits<T>::data_type getComp(const Assembly & myassy)
{
    ...
}

这样一个电话

getComp<TYPEA>(thisassy)

将返回对As的引用,因此我可以在向量级操作并访问每个组件对象的方法和数据:

getComp<TYPEA>(thisassy).push_back(newcomponentA);
getComp<TYPEA>(thisassy).back().methodA1();
getComp<TYPEA>(thisassy).front().data1 = 5.0;

谢谢,

和田

1 个答案:

答案 0 :(得分:1)

特质不会在这里做你想做的事。 C ++缺乏内省支持所说的“让我成为Y类的第一个X类成员”。此外,特征旨在“告诉我更多关于X型”的操作。

模板专业化可以用于此,但它们将是很多工作:

template<class T>
T& getComp<T>(Assembly& assy);

template<>
ComponentA& getComp<ComponentA>(Assembly& assy)
{ return assy.As;
}

template<>
ComponentB& getComp<ComponentB>(Assembly& assy)
{ return assy.Bs;
}

template<>
ComponentC& getComp<ComponentC>(Assembly& assy)
{ return assy.Cs;
}

template<>
ComponentD& getComp<ComponentD>(Assembly& assy)
{ return assy.Ds;
}

或更短:

template<class T>
T& getComp<T>(Assembly& assy);

#define SpecializeGetComp(T, field) template<> \
T& getComp<T>(Assembly& assy) { return assy.field; }

SpecializeGetComp(ComponentA, As)
SpecializeGetComp(ComponentB, Bs)
SpecializeGetComp(ComponentC, Cs)
SpecializeGetComp(ComponentD, Ds)

您可能还想阅读Alexandrescu的书 Modern C ++ Design 中的类型列表(第3章)。您可能能够以类似工厂的模式使用它们,但这不仅仅是一个SO答案。