クラスを提供し、それを使用した評価をサポートするライブラリを作成していますA
(基本的に中置表記による代入と式)。不必要に複雑にせず、割り当てだけを見てみましょう。ユーザーは次のようなことができます。
A a0,a1;
a0=a1;
a1=a0;
同時に、ライブラリは操作も提供する必要があります。 let call itfuse
は、任意の数のそのようなステートメントを取ります。
fuse(
a0=a1,
a1=a0
);
の有無にかかわらず、同じ構文を使用する必要がありますfuse
。これを機能させるには、非標準の代入演算子 (参照を返すのではなくA
、ステートメントを表すオブジェクトを返すもの) と別のassign
メソッドが必要です。
struct A {
B operator=(const A& a) {
B b(*this,a);
return b;
}
A& assign(const A& a) { // does the actual work }
};
はB
ステートメントをラップしようとします。代入操作は の破棄でトリガーされB
ます。
struct B {
B(A& dest,const A& src) : calc(true), dest(dest), src(src) { }
B(B&& b) : calc(b.calc), dest(b.dest), src(b.src) { b.calc=false; }
~B() {
if (calc)
dest.assign(src);
}
bool calc;
A& dest;
const A& src;
};
boolcalc
は、このステートメントが評価を必要とするかどうかを追跡します。操作にはfuse
、可変個引数ブロックが付属しています。
struct fuse {
template<typename... Bs>
fuse(Bs&&... bs) {
// Recurse and evaluate...
}
};
このセットアップには重大な欠陥があります。移動コンストラクターを呼び出すコンパイラーに依存しています。コピー省略規則のため、そのようなことはできません。
コピー/移動コンストラクターなしでそれを行う方法は?