[cppll:0364] <tips> viva comma ( was: Re: <tips> expression )

Subject:
[cppll:0364] <tips> viva comma ( was: Re: <tips> expression )
From:
Wraith the Trickster <wraith@...>
Date:
Thu, 27 Dec 2001 11:23:28 +0900
X-Mailer:
Microsoft Outlook Express 5.50.4807.1700
Message-Id:
<003201c18e7d$84e8f3c0$acee12d3@mist>
References:
340
道化師です。

[cppll:0340] Re: <tips> expression】
> <tips>がいつのまにか<tricks>や<magics>になっちゃって、

内容に関してはすでそーなっている気が...。(^^;


[cppll:0340] Re: <tips> expression】
>  , なんかも再定義できます。
>
> でもよいこのみんなは真似しちゃだめだよ。

...というリクエスト( ←違うって )にお応えして、カンマ演算子の
再定義を御題に二つほど...


■choose result

定義:
 template<class T> struct comma_result {
   T &value;
   comma_result(T &_value) :value(_value) {}
 };
 template<class T> inline comma_result<T> comma_set(T &value) {
   return comma_result<T>(value);
 }
 class comma_get {};
 template<class T, class U>
 inline comma_result<T> & operator,(comma_result<T> &result, U) {
   return result;
 }
 template<class T>
 inline T & operator,(comma_result<T> &result, comma_get) {
   return result.value;
 }

用例:
 hoge = (A, B, comma_set(C), D, E, F, comma_get());

目的:
 通常カンマ演算子で区切られた値はその最後の値が全体の評価値と
 して扱われるんだけど、これを使うことで途中の値を全体の評価値
 にできる。


■enumerate element

定義:
 template<class T> struct enum_adapter {
   T &value;
   enum_adapter(T &_value) :value(_value) {}
 };
 template<class T> inline enum_adapter<T> enum_start(T &value) {
   return enum_adapter<T>(value);
 }
 class enum_end {};
 template<class T> inline enum_adapter<T>
 operator,(enum_adapter<T> container, const T &element) {
   container.value.push_back(element);
   return container;
 }
 template<class T>
 inline T & operator,(enum_adapter<T> container, enum_end) {
   return container.value;
 }

用例:
 hoge(enum_start(demi< std::list<int> >()()), 1, 2, 3, 4, enum_end());

目的:
 コンテナへ複数の値をまとめて代入。インラインで使用可。

# demi は http://www.tietew.jp/cppll/archive/167 のものを使用。


[cppll:0340] Re: <tips> expression】
> 'ε'や'道'が大喜びしちゃうからね。

んだ、んだ。


...ちなみに上記のネタは二つとも VC6 ではダメ、お話になんない。
VC6 でカンマ演算子の再定義を利用することはあきらめませう。
他のコンパイラはというと、BCC5.5, CW6 では OK 。BC5 では最後の
部分を...

 ...., D, E, F).value;

...などとすれば大丈夫。でね、でね、よくわかんないのが、enum_start
の引数。上記用例では demi をかましているんだけど、demi を使わな
いと BCC5.5 も CW6 もコンパイラが文句たれだすの。で、demi をかま
さなくても...

 std::list<int> hoge;
 enum_start(hoge), 1, 2, 3, 4, 5, enum_end();

...という形なら OK 。なんなんだろう?で、gcc/g++ ではどーかと、
試してみたら choose result はすんなり動くんだけど、enumerate
element は定義もいじりながらいろいろやってみたんだけど全然うま
くいかない。choose result が大丈夫なんだからもうちょっと頑張れ
ばうまくいくようにはなるとは思うんだけど...。

# VC7 ではどうでしょう? > 誰ぞ。

□■□■                  Wraith the Trickster                  □■□■
■□■□ 〜I'll go with heaven's advantage and fool's wisdom.〜 ■□■□

スレッド

Navigation

検索

[検索ヘルプ]

Maintener: Tietew <www.tietew.jp>
Powered by Ruby on Rails, Mongrel, PostgreSQL, and Hyper Estraier.
click here