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

发布于 2024-12-10 18:11:59 字数 1018 浏览 0 评论 0原文

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

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

我想使用特征并定义一个可以返回对成员的引用的函数,如下所示:

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;

谢谢,

Wada

I have a class that holds several vectors of objects:

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

I would like to use traits and define a function that can return reference to members like this:

template< int T >
struct ComponentTraits;

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

such that a call

getComp<TYPEA>(thisassy)

would return a reference to As so I can manipulate at the vector level and access each component object method and data:

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

Thanks,

Wada

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月依秋水 2024-12-17 18:11:59

在这里,特质不会做你想做的事。 C++ 缺乏“给我第一个 X 类 Y 类型成员”所需的内省支持。此外,特征旨在用于“告诉我更多有关 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 的《现代 C++ 设计》一书中的类型列表(第 3 章)。您也许可以以类似于工厂的模式使用它们,但这远比 SO 答案真正适合的方式要多。

Traits aren't going to do what you want here. C++ lacks the introspection support needed to say, "Get me the first member of class X that is of type Y." Also, traits are intended for "tell me more about type X" kinds of operations.

Template specialization can be used for this, but they'll be a lot of work:

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

Or shorter:

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)

You may also want to read up on Typelists (Chapter 3) in Alexandrescu's book Modern C++ Design. You might be able to use them in a Factory-like pattern, but that's way more than an SO answer really fits.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文