0
struct Type
{
  auto opBinary(string op)(Type other) const {
    return Type();         // #1 return type is Type
    return typeof(this)(); // #2 return type is const(Type)
  }
}

unittest
{
  Type t1, t2;
  auto t3 = t1 + t2;
}

ではt1.opBinary!("+")(t2)t1定数になりますが、t2非定数のままです。opBinaryの戻り値の型はTypeorconst(Type)である必要がありますが、その理由は?

const(T)はスーパータイプなので、 を返す必要があるかもしれませんがconst、実際にはこれをほとんど見たことがありません。これらの型を使用する、またはそれらの型によって使用される型と関数の階層を扱う場合、物事はかなり複雑になります。

4

2 に答える 2

4

ここでの戻り値は新しいオブジェクトなので、非 const にすることをお勧めします。新しいため、安全に変更できるため、不必要に const で制限する理由はありません。

既存のオブジェクトの一部を返す場合は、const の代わりに inout を使用する必要があります。inout は、オブジェクトの定数も戻り値になることを意味します。

inout(Type) opBinary(string op)(Type other) inout {
    return whatever;
}

const(Type) オブジェクトを使用すると、戻り値も const になり、可変オブジェクトで呼び出された場合、戻り値も可変になります。

于 2013-01-25T22:40:22.960 に答える
1

戻り値の型は T または const(T) のどちらにする必要がありますか? どれでも構いません。

どちらの方がよいですか?意図した動作によって異なります。

opBinary のconst修飾子は、非表示の「this」引数がconstであることを意味するだけです。それ以上、他には何もありません。戻り値の型については何も意味しません。それはすべて、非常に単純な選択に要約されます。

struct Type
{
    int a;
    auto opBinary(string op)(Type other) const
           if (op == "+")
    {
        return Type(this.a + other.a);
    }
}

void main()
{
    Type first, second;
    (first + second).a = 42; // Do you want to allow this?
                             // Yes -> return non-const
                             // No -> return const
}

引数の修飾子を保持したい場合は、inout (Adams の回答を参照) または修飾子の手動チェックを使用して、より複雑な選択を行います。

どちらを選択しても、自動型推定が記憶されます。

auto third = first + second;
third.a = 42; // Error if returns const

Type fourth = first + second;
fourth.a  = 42; // Fine in both cases, struct was copied

最後に、クラス/構造体がどのように動作するかは、型設計者としてのあなたの意図についてです。

于 2013-01-26T11:44:51.000 に答える