...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

型の制約の緩和

Dは関数の引数と戻り値の型がmutable/const/invariantのどれなのか把握するのが大変すぎる.
これを安全性を落とさずに緩和する方法が欲しい.
掲示板のコードを少し整形したものをぺたりしてみる.

class A {
    int mem;
    this(int m) {mem=m;}
    const A opClone() {return new A(mem);}//手作業でクローンを作って返す
    const invariant(A) opInvariantClone() {return new invariant(A)(mem);}//同上
}
void f(A x) {/*...*/}
void g(const(A) x) {/*...*/}
void h(invariant(A) x) {/*...*/}

void main() {
    f(new A); 
    f(new const(A));//opClone()が暗黙的に呼ばれる
    f(new invariant(A));//opClone()が暗黙的に呼ばれる

    g(new A);
    g(new const(A));
    g(new invariant(A));

    h(new A);//opInvariantClone()が暗黙的に呼ばれる
    h(new const(A));//opInvariantClone()が暗黙的に呼ばれる
    h(new invariant(A));
}

仕組み

つまりopAddなどのそれと同様にこれが

A x = new invariant(A);

これに変換され

A x = (new invariant(A)).opClone();

これが

invariant(A) x = new A;

これに変換される

invariant(A) x = (new A).opInvariantClone();

安全性を確保するために

opCloneが未定義のときにconst/invariant -> mutable
opInvariantCloneが未定義のときにmutable/const -> invariant
に変換しようとしたときは今までどおりエラーになって参照型メンバのディープコピー忘れを防止する.


真面目にこういうのが欲しいのだけどダメなのだろうか.