我希望能够使用可变数字扩展我的coroutine类 “i / o pins”,但这些需要访问主类。 另外,我不想主要为pin对象添加额外的指针 因为很难找到一个正确初始化它们的地方。 所以我找到了一个解决方法:
template< int base_offs > struct pin {
int y1;
void test( void );
};
template< class pin1, class pin2 > struct wrap0 {
int x1;
char x2;
pin1 r3;
pin2 r4;
};
template< int base_offs >
void pin<base_offs>::test( void ) {
typedef wrap0< pin<0>,pin<0> > wrap;
wrap& W = *(wrap*)(((char*)this)-base_offs);
printf( "y1=%i W.x1=%i W.x2=%i\n", y1, W.x1, W.x2 );
}
typedef wrap0< pin<0>,pin<0> > wrap1;
typedef wrap0< pin< offsetof(wrap1,r3) >, pin< offsetof(wrap1,r4) > > wrap;
wrap Z = {456,123,33333,44444};
int main( void ) {
Z.r3.test();
Z.r4.test();
}
VC build:http://rextester.com/MXO25153
gcc build:http://ideone.com/987JP5
现在,问题:
有没有办法在初始类声明期间计算offsetof? (即像这样:http://ideone.com/tomF0T)
是否有更好的编译时解决方案来解决包装器访问问题?
答案 0 :(得分:0)
嗯,这是一个版本,但VC不支持它。 但IntelC和gcc确实如此。
template< class wrap, class pad, pad wrap::*X > struct pin {
int y1;
void test( void ) {
wrap& W = *(wrap*)(((char*)this) - size_t(&(((wrap*)0)->*X)) - sizeof(pad));
printf( "y1=%i W.x1=%i W.x2=%i\n", y1, W.x1, W.x2 );
}
};
struct wrap {
int x1;
char x2;
typedef pin< wrap, char, &wrap::x2 > r3_t;
r3_t r3;
typedef pin< wrap, r3_t, &wrap::r3 > r4_t;
r4_t r4;
};
wrap Z = {456,123,33333,44444};
int main( void ) {
Z.r3.test();
Z.r4.test();
}
VC:http://rextester.com/QFY31637 gcc:http://rextester.com/HEN91787
答案 1 :(得分:0)
这是另一个版本,可能是最终版本,因为 它兼容VC和gcc,并不是真的 有任何恼人的副作用。 当然,函数通常不是“编译时”,而是在 无论如何,它的内联和优化都是常量。
template< class wrap, int (*base_offs)(void) > struct pin {
int y1;
void test( void ) {
wrap& W = *(wrap*)(((char*)this) - ((*base_offs)()) );
printf( "ofs=%i y1=%i W.x1=%i W.x2=%i\n", ((*base_offs)()), y1, W.x1, W.x2 );
}
};
struct wrap {
int x1;
char x2;
static int get_r3(void) { return offsetof(wrap,r3); }
pin< wrap, get_r3 > r3;
static int get_r4(void) { return offsetof(wrap,r4); }
pin< wrap, get_r4 > r4;
};
wrap Z = {456,123,33333,44444};
int main( void ) {
Z.r3.test();
Z.r4.test();
}
VC:http://rextester.com/NPBY12766 gcc:http://rextester.com/XWI48752