Первое, о чем я подумал, - это использование миксина, который кажется идеальным решением, однако он не поддерживает операторы.
Еще одна альтернатива - обернуть результат в структуру, а затем неявно вернуть обратно структуру. в FooBar. Идея состоит в том, что нам нужна промежуточная структура для обработки всего в стеке.
class Foobar {
public int value;
public this(int val) {
value = val;
}
public static TempFoobar operator+(Foobar lhs, Foobar rhs) {
let result = new Foobar(lhs.value + rhs.value);
return TempFoobar(result);
}
}
struct TempFoobar {
Foobar result;
public this(Foobar val) {
result = val;
}
public void Replace(Foobar val) mut {
delete result;
result = val;
}
public static TempFoobar operator+(TempFoobar lhs, Foobar rhs) {
var copy = lhs;
let result = new Foobar(lhs.result.value + rhs.value);
copy.Replace(result);
return copy;
}
public static implicit operator Foobar(TempFoobar temp) {
return temp.result;
}
}
class Program {
static mixin Add(Foobar lhs, Foobar rhs) {
let result = scope:mixin Foobar(lhs.value + rhs.value);
result
}
public static void Main() {
Test();
Console.In.Read();
}
public static void Test() {
Foobar a = scope Foobar(5);
Foobar b = scope Foobar(5);
Foobar x = scope Foobar(20);
//let c = Add!(Add!(a, b), x); //Mixin version
Foobar c = (a + b) + x;
defer delete c;
Console.Write("{}", c.value);
}
}
Конечно, я бы избежал перегрузки операторов, если это действительно ... действительно имеет смысл, и никогда не возвращал бы экземпляр кучи из функция без ключевого слова, такого как 'create' или 'new' в имени функции.
Примечание, в данном конкретном случае c вы можете просто использовать int в качестве промежуточного объекта
public static int operator+(Foobar lhs, Foobar rhs)
{
return lhs.value + rhs.value;
}
public static int operator+(int lhs, Foobar rhs)
{
return lhs + rhs.value;
}
public static implicit operator Foobar(int temp) {
return new Foobar(temp);
}
Опять же, я не рекомендую делать это.