これは・・・

zxc
記事: 79
登録日時: 13年前
住所: 日本の背骨(?)あたり

これは・・・

投稿記事 by zxc » 10年前

 DxLibが提供してくれる描画関数は機能や描画に利用する座標の型などで複数ある。その中から幾つかを利用したいと考えたときに、描画する関数の幾つかには共通の意味合いを持つ引数を持つものがある場合がある。これを関数ごとにオーバーロードだテンプレートだのしてもやりたいことが出来ないわけではないだろうが、同じ意味合いの型を複数の場所に独立に記述するというのは後々に手直ししたり、利用できる型を追加しようとするときに、その関数の数だけコピペするというのはとても嫌だ。

 そんなこんなである要求を満たした型を想定して、それ以外の型は弾くが要求を満たす型ならどんな型でも利用可能なコンセプト的なことがしたい。でも知る限りではまだconceptキーワードは使えないし、利用している環境はvc2010だから尚のこと使えるとは思えない。そこでtraitsを使って書いてみた。例えば下の関数はDrawTurnGraph/DrawTurnGraphF関数をラップしているつもり。一応コンパイルも通るしきちんと描画されているみたいだが、正直追いきれる自身はない。

CODE:

		template
		inline int DrawTurnGraph( const Point& p, const GH& g, const TransFlag& trans ){
			typedef zxc::img::ImageDrawingTraits traits;
			return ( 
				zxc::img::DrawTurnGraph(
					traits::x(p), traits::y(p),
					traits::gh(g), traits::trans_flag(trans))
						);
		}

  今更だけれど、これはごく一部の関数にしか共有されない引数でやると旨みが少ないと思うが、ここまできたら全ての引数をtraitsで用意してしまうべきという気もしてきて迷う。

アバター
Ketty
記事: 103
登録日時: 11年前

Re: これは・・・

投稿記事 by Ketty » 10年前

うう・・むずかしい・・・。
旨味成分がいったいどこにあるのかわからないです(><)
私の知識が浅いので、プログラムも正しく読み取れていません。
最近templateを覚えた程度ですので・・・ご容赦ください(汗)

これは簡単にいうと、int指定でもfload指定でも受け入れてくれそうな便利ラップ関数かなぁと思うんですが、
だとすると、よけいにメリットがクエスチョンです(?_?)

DxLibということは、座標系ならintかfloat、フラグ系なら(BOOL)TRUE/FALSEだと思いますが、
例えば座標系にdoubleをぶちこんでしまったら・・・どうなるのですか??内部的にはいい感じにintかfloatにキャストされる?
もちろん、intにするかfloatにするか、その仕様は、自分で決めておられるのだと思いますが、
だとすると、DrawTurnGraph!とかDrawTurnGraph"F"!とか、明示的に書くのも、
自分のさじ加減だから、結局おなじことではないかと思うんです(^^; ←浅はかでしたらすみません。

あるいは、型を意識しなくてよい、ということがメリットだとすると、
逆説的に、型を意識しなくて済んでしまう脅威があるとも思えます。
(TransFlag引数に"a"という文字列を渡したら、内部的に透過指定=FALSEで処理されてて、意図していた動きじゃなくなってた・・・みたいな)

的外れでしたらすみません

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前

Re: これは・・・

投稿記事 by MoNoQLoREATOR » 10年前

座標に実数型を与えたら四捨五入する仕様だったら嬉しいですね。

zxc
記事: 79
登録日時: 13年前
住所: 日本の背骨(?)あたり

Re: これは・・・

投稿記事 by zxc » 10年前

Ketty さんが書きました: これは簡単にいうと、int指定でもfload指定でも受け入れてくれそうな便利ラップ関数かなぁと思うんですが、
だとすると、よけいにメリットがクエスチョンです(?_?)

DxLibということは、座標系ならintかfloat、フラグ系なら(BOOL)TRUE/FALSEだと思いますが、
例えば座標系にdoubleをぶちこんでしまったら・・・どうなるのですか??内部的にはいい感じにintかfloatにキャストされる?
もちろん、intにするかfloatにするか、その仕様は、自分で決めておられるのだと思いますが、
だとすると、DrawTurnGraph!とかDrawTurnGraph"F"!とか、明示的に書くのも、
自分のさじ加減だから、結局おなじことではないかと思うんです(^^; ←浅はかでしたらすみません。
 これはtraitsというパターンというかイディオムを利用したものです。
 doubleはまだサポートしてなかった気がします。仮にしていたらstatic_castでfloatにキャストしますし、サポートしていないならstatic_assertでコンパイル時にそれが分かるはず・・・・です。一応doubleのサポートも後回しになるでしょうけど考えています。確かstd::pair、std::pair、自己定義型のPointなど、x座標とy座標を纏めて管理するクラスや構造体も病が座標については既にサポート、もしくはあとでサポートしやすいようにしたつもりです。
 
 intかfloatかが重要なのではなく、ある共通の目的のために利用される型ならどんなものでも、型の違いを気にして関数を自分で書き分けるより、勝手にオーバーロードだので解釈してもらうほうが楽だと考えています。この"楽さ"が重要です。 「常に型に応じた関数を書き分けないといけない」 のか 「もし必要なら(例えばDrawTurnGraph/DrawGraphF)書き分けても良い」 の違いが生まれると思います。また、例えば座標に関するこのtraitsなら、似たような意味合いの引数を要求する関数全てに流用が可能です。

 フラグもintかbool以外ではstatic_asssertで引っかかり、intとboolのどちらであっても得られるフラグは(DxLibにおいてフラグを管理する型であることが多い)int型のTrueかFlaseになっていたと思います。 (一応TrueとFalseはマクロではなくstatic const int型の変数です)

 
 なのでそれなりに適切な型でないとstatic_assertで停止しますし、後に利用できても問題ないだろう型が出てきたとしても、特殊化でその型を追加してやれば良いのです。

アバター
Ketty
記事: 103
登録日時: 11年前

Re: これは・・・

投稿記事 by Ketty » 10年前

おお・・・、ご返答くださり、ありがとうございますm(__)m
ご教示いただいた内容を、私は、おそらくまだ理解できておりません。

分かったこととしては、
適切な型でなければコンパイル時エラー通知される、という仕組みなのですね。
static_assertというものを知らなかったので勉強になりました・・・。
traitsについては、いま勉強していますm(__ ; )m