在C中编写structarray map functor的最简单方法
这是对最可读方式的意见的调查 – 无论是使用C指针到成员,字节偏移还是模板化仿函数来定义“从结构foo中选择成员X”.
我有一个包含大量结构的类型,我正在编写一个实用函数,它基本上在某些范围内作为reduce运行.每个结构将一组因变量与一个独立维度的某个点相关联 – 发明一个简化的例子,想象这会记录一段时间内房间的一系列环境条件: // all examples are psuedocode for brevity struct TricorderReadings { float time; // independent variable float tempurature; float lightlevel; float windspeed; // etc for about twenty other kinds of data... } 我的函数只是执行cubic interpolation来猜测可用样本之间某些给定时间点的条件. // performs Hermite interpolation between the four samples closest to given time float TempuratureAtTime( float time,sorted_vector<TricorderReadings> &data) { // assume all the proper bounds checking,etc. is in place int idx = FindClosestSampleBefore( time,data ); return CubicInterp( time,data[idx-1].time,data[idx-1].tempurature,data[idx+0].time,data[idx+0].tempurature,data[idx+1].time,data[idx+1].tempurature,data[idx+2].time,data[idx+2].tempurature ); } 我想概括一下这个功能,以便它可以一般地应用于任何成员,而不仅仅是温度.我可以想到三种方法来做到这一点,虽然它们都很容易编码,但我不确定从现在起一年内使用它的人最可读的是什么.这是我正在考虑的事情: 指向成员的语法 typedef int TricorderReadings::* selector; float ReadingAtTime( time,svec<TricorderReadings> &data,selector whichmember ) { int idx = FindClosestSampleBefore( time,data ); return CubicInterp( time,data[idx-1].*whichmember,/* ...etc */ ); } // called like: ReadingAtTime( 12.6f,data,&TricorderReadings::windspeed ); 这感觉就像最“C y”的方式,但它看起来很奇怪,整个指针到成员的语法很少使用,因此我的团队中的大多数人都很难理解.这是技术上“正确”的方式,但也是我将收到最混乱的电子邮件的方式. 结构偏移 float ReadingAtTime( time,int memberoffset ) { int idx = FindClosestSampleBefore( time,*(float *) ( ((char *)(&data[idx-1]))+memberoffset ),offsetof(TricorderReadings,windspeed) ); 这在功能上与上面相同,但是指针数学是明确的.这种方法对于我的团队中的每个人(在C之前都学过C)都会立即熟悉和理解,并且它很强大,但它看起来很蹩脚. 模板化的Functor template <class F> float ReadingAtTime( time,svec<TricorderReadings> &data ) { int idx = FindClosestSampleBefore( time,F::Get(data[idx-1]) ),/* ...etc */ ); } // called with: class WindSelector { inline static float Get(const TricorderReadings &d) { return d.windspeed; } } ReadingAtTime<WindSelector>( 12.6f,data ); 这是最直接和STL-ish的做事方式,但它似乎是一大堆额外的输入和语法和即兴的类定义.它编译成几乎与上面两者完全相同的东西,但它也在可执行文件中转储了一堆冗余函数定义. (我已经用/FAcs对此进行了验证,但也许连接器会再次将它们取出来.) 以上三个都可以工作,编译器为所有这些代码发出几乎相同的代码;所以,我必须做出的最重要的选择就是最具可读性.你怎么看? 解决方法
如果你的团队由相当聪明的人组成,我会说要信任他们和他们的能力,并使用指针到成员语法提供的技术上首选的解决方案.这是它的目的.
如果你真的担心,你可以采取一些措施来缓解未来的麻烦 >在typedef附近的注释中注明并将其称为“指向成员的指针”语法,以便其他团队成员知道要查找的内容 其他两种方法都存在问题,如您所描述的以及其他方面: >两者都需要更多代码,有更多的拼写错误空间等. 由于C语言中结构的扩展功能,在这种语言中,offsetof的使用仅限于“POD类型”,对于类,或多或少对应于结构的C概念(尽管非派生类只有公共非 – 虚拟成员函数,没有构造函数和/或析构函数也可以作为POD). 从here起. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |