0

可変数の「i/o ピン」でコルーチン クラスを拡張できるようにしたいのですが、これらはメイン クラスにアクセスする必要があります。また、ピン オブジェクトに余分なポインターを追加したくありません。これは主に、それらを適切に初期化する場所を見つけるのが難しいためです。だから私は一種の回避策を見つけました:

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 ビルド: http://rextester.com/MXO25153

gcc ビルド: http://ideone.com/987JP5

さて、質問:

  1. 初期クラス宣言中にoffsetofを計算する方法はありますか? (つまり、このように: http://ideone.com/tomF0T )

  2. ラッパーアクセスの問題に対するより良いコンパイル時の解決策はありますか?

4

2 に答える 2

0

ここに 1 つのバージョンがありますが、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

于 2013-11-09T14:27:15.793 に答える
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

于 2013-11-10T23:51:58.103 に答える