expression template

go-(http://d.hatena.ne.jp/w_o/20061018#p1)を書いてたときに、右結合ができなくて、無理矢理左結合の演算子を右結合にするというのをやったんだけど、多分それがexpression templateなんじゃないかとふと思ったのだった。


expression template については適当にぐぐって(ぐぐられるexpression templateたち)。要するに、構文木がいじれちゃうわけ。まあ、なんてことかしら。構文木を変換するマクロを書けるのは、Lispだけの特権じゃないんだよ。

なんか例を書こうと思ったけどめんどうなのでやめた。


go- でいうと、gos.hppの

static inline detail::ConsConstructor<CScmObj> operator >>(CScmObj a, CScmObj b) {
	return detail::ConsConstructor<CScmObj>(a,b);
}
static inline detail::ConsConstructor<CScmObj> operator >>(Symbol a, CScmObj b) {
	return detail::ConsConstructor<CScmObj>( CScmObj(a), b );
}

このへんとか

template <typename T>
struct ConsConstructor {
	T car;
	CScmObj cdr;

	CScmObj construct( CScmObj cdr ) {
		ScmPair *pair = SCM_NEW(ScmPair);
		SCM_SET_CAR( pair, this->cdr );
		SCM_SET_CDR( pair, cdr );

		return car.construct( CScmObj( reinterpret_cast<ScmObj>(pair)) );
	}

	ConsConstructor ( const ConsConstructor<T> &c )
		:car(c.car), cdr(c.cdr) {}

	ConsConstructor(T car,CScmObj cdr)
		:car(car), cdr(cdr) {}

	operator CScmObj() {
		ScmPair *pair = SCM_NEW(ScmPair);
		SCM_SET_CAR( pair, cdr );
		SCM_SET_CDR( pair, SCM_NIL );
		
		return car.construct( CScmObj(reinterpret_cast<ScmObj>(pair)) );
	}
};
template <>
struct ConsConstructor<CScmObj> {
	CScmObj car;
	CScmObj cdr;

	CScmObj construct( CScmObj cdr ) {
		ScmPair *pair1 = SCM_NEW(ScmPair);
		SCM_SET_CAR( pair1, this->cdr );
		SCM_SET_CDR( pair1, cdr );
		ScmPair *pair2 = SCM_NEW(ScmPair);

		SCM_SET_CAR( pair2, car );
		SCM_SET_CDR( pair2, reinterpret_cast<ScmObj>(pair1) );

		return reinterpret_cast<ScmObj>(pair2);
	}

	ConsConstructor ( const ConsConstructor<CScmObj> &c )
		:car(c.car), cdr(c.cdr) {}

	ConsConstructor(CScmObj car,CScmObj cdr)
		:car(car), cdr(cdr) {}

	operator CScmObj() {
		ScmPair *last = SCM_NEW(ScmPair);
		SCM_SET_CAR( last, cdr );
		SCM_SET_CDR( last, SCM_NIL );

		ScmPair *pair = SCM_NEW(ScmPair);
		SCM_SET_CAR( pair, car );
		SCM_SET_CDR( pair, (ScmObj)last );

		return reinterpret_cast<ScmObj>(pair);
	}
};

このへん。全く説明無しなんだけど…operator >>が構文木を作ってるだけ。評価はしない。
そうすると、

a >> b >> c >> d

こういうのが、

((a >> b) >> c) >> d

     /\
    /\ d
   /\ c
  a  d

こうなるよね。そんでconstruct()すると…やっぱめんどうだからいいや。説明になってねー。


http://www.radiumsoftware.com/0306.html#030611
おっと。手を出してはいけないらしい。