1

次のコードを検討してください。

immutable struct Test {
    this(int foo) { }

    int opApply(int delegate(ref int) dg) {
        return (0);
    }
}

int main(string[] argv) {
    auto set = Test(); // compiles
    // auto set = Test(1); // Error: cannot uniquely infer foreach argument types

    foreach (item; set) { }

    return 0;
}

デフォルトの引数のないコンストラクターを使用しTestて構造体を構築すると、コードは正常にコンパイルされますが、他のコンストラクターを使用しようとすると、コンパイル時エラーが発生します。をコメントアウトするforeachと、コードがコンパイルされます。をコメントアウトするimmutableと、コードもコンパイルされます。

この種の動作の理由は何ですか?また、どのように修正する必要がありますか?

4

1 に答える 1

3

実際、少なくとも DMD バージョン 2.059 を使用すると、どちらのコンストラクターでもコンパイルされません (Windows 7 と FreeBSD でテスト済み)。

この理由はかなり明白なはずです。構造体 (またはクラス) を不変にすることで、単にその構造体 (またはクラス) のすべてのメンバーに不変を適用するだけです。ただし、コンストラクターは不変にはなりません。immutable struct Testつまり、次のことを効果的に行ったと宣言したときです。

struct Test {
    this(int foo) { }
    immutable int opApply(int delegate(ref int) dg) {
        return (0);
    }
}

immutableforeach ループをコメント アウトすると、コードをコンパイルできます。これは、foreach が宣言なしで opApply メソッドを探しているためです。

やろうとしていることに応じて、構造体finalの代わりに構造体を作成するimmutableか、ほとんどの構造体を不変に保ちたい場合は...

struct Test {
    // Anything that needs to be mutable should go up here
    int opApply(int delegate(ref uint) dg) {
        return 0;
    }

    // Anything put in this block is immutable
    immutable {
        this(int foo) { }
    }
}
于 2012-04-24T17:46:48.227 に答える