プロパティ
プロパティ定義するテンプレートとか誰か書いてたっけ…ということでとりあえず的にgetterとsetterを書いてみました。
typeof(var) setter(alias var)(typeof(var) t){ return var = t; } typeof(var) getter(alias var)(){ return var; } class Hoge{ int x_; alias setter!(x_) x; alias getter!(x_) x; }
普通。
次は両方同時に定義するテンプレートを書きましょう。Rubyのattr_accessorのような。
template accr(alias var){ alias getter!(var) accr; alias setter!(var) accr; } class Hoge{ int x_; alias accr!(x_) x; }
これはいけません。accrのメンバが関数一つではないために、accrはaccr!(var).accrの省略記法にはならないからです。
正しくは「alias accr!(x_).accr x」になりますが、ダサいのでどうにかしたいところ。
これはテンプレートを一つ間に挟むことでうまくいきます。
template accr_(alias var){ alias getter!(var) accr_; alias setter!(var) accr_; } template accr(alias var){ alias accr_!(var).accr_ accr; }
なんていうか変数宣言もめんどくさいし勝手にやってくれよ…という人のために、変数も宣言してくれるテンプレートも欲しい。
まあとりあえずテンプレートに変数持たせとけばいいじゃん、という事で下のような感じに。
template prop_(T){ T var; alias getter!(var) prop_; alias setter!(var) prop_; } template prop(T){ alias prop_!(T).prop_ prop; }
しかしこれは下のようなコードで問題になります。
class Hoge{ alias prop!(int) x; alias prop!(int) y; // y は x の単なる別名! }
しょうがないなあ…ということで引数を増やします。
template prop_(T, char[] name){ T var; alias getter!(var) prop_; alias setter!(var) prop_; } template prop(T, char[] name){ alias prop_!(T, name).prop_ prop; } class Hoge{ alias prop!(int, "x") x; alias prop!(int, "y") y; }
実に冗長ですが、実体化するたびに違う型(または値)を返すテンプレートを書けそうにないのでこんな風にするしかないです…
実体化するたびに違う型を返すテンプレートは、違う場面でも欲しいことがあるのですが、関数型的にはいただけないんだろうなあ。
他にも問題はあります。一つが「T var」に直接アクセスする方法が無いこと。
これは x._ とかで何とかならないかなあ…と思ったんですがなりませんでした。よく考えなくても x はテンプレートの別名ではなく関数の別名なので、そりゃそうだよねそりゃそうさという感じです。
おかげで op= や ++ を使えませんが、まあWalterたん何とかして下さい…ということに。
あと、id:shinichiro_hさんに指摘されるまで気づいてなかったんですが、aliasによるテンプレートの実体化は定義時の一度だけなので、よく考えなくてもこれ静的変数じゃん、という。なんて使えないんだ…!
そもそも、アクセサの利用目的を考えると、変数とアクセサを同じシンボルから定義する意味なんて全く無いですし、どうでもいいと思いました。
まあ getter setter accr は実用に供するのではないかと思います…そうか?全然そうと思えない自分がいます。