それは不可能; a が代入される前に、operator + (b, c) を呼び出した結果として一時オブジェクトが作成されます。この演算子は、作成されたインスタンスを返す必要があります。これは、に割り当てられる必要があります。作成されたインスタンスは常に b + c によって作成されます。
ただし、 += をメンバー演算子として定義して、次のように言うことができます。
b += c;
これにより、余分なコピーを作成せずに b の値が変更されます。
編集:私は再考しました:)
操作を遅延評価オブジェクトとして抽象化することで、間違いなくそれを行うことができます。
次に例を示します。
class MyClass; // fwd. declaration of your class
struct LazySum
{
LazySum(const MyClass& a, const MyClass& b)
: x(a), y(b) {}
float operator[](int i) { return x[i] + y[i]; }
const MyClass& x;
const MyClass& y;
};
class MyClass
{
public:
MyClass(int N)
{
data_ptr = new float[n = N];
};
int n; // this shouldn't be public
float* dat_ptr; // nor this, but I went with your code
// ... clever operator definition here ...
MyClass& operator=(const LazySum& terms)
{
// ignore case when n != x.n or n != y.n
// because not the point of the example
// (and I'm lazy)
// sum evaluation occurs here
// with no new allocations
for(int i = 0; i < n; ++i)
data_ptr[i] = terms[i];
return *this;
}
};
LazySum operator=(const MyClass& x, const MyClass& y)
{
return LazySum(x, y); // LazySum is a couple of references in size
}
void client_code_using_clever_op()
{
MyClass a(4);
MyClass b(4);
MyClass c(4);
// modify b.data_ptr and c.data_ptr ....
// Use "clever operator"
a = b + c; // actual sum performed when operator = is executed
}
アイデアは、項を保存し、項に対して後期評価を実行することです。
改善点:
LazySum の構築にファンクターを挿入して LazyOp にします (ファンクターは op が何であるかを決定します)。それに関して、MyClass に他の二項演算子を実装します。
MyClass で RAII を使用します。
別の型 (例: some ) に遅延評価演算子を実装する必要がある場合はMyOtherClass
、項およびファンクター型のテンプレートとして LazyOp を実装することを検討してください。
これは、追加の作業なしでは、より複雑な式をサポートしていません。
MyClass a(4)、b(4)、c(4)、d(4);
d = (a + b) + c; // エラー
operator+(const LazySum&, const MyClass&);
この例は、 ;が必要なため機能しません。