我正在编写一个库,它提供一个类A
并支持用它进行评估(基本上带有中缀符号的赋值和表达式)。让我们不要让事情不必要地复杂化,只看作业。用户可以执行以下操作:
A a0,a1;
a0=a1;
a1=a0;
同时,库还应该提供一个操作,让我们调用它fuse
,它接受任意数量的此类语句:
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...
}
};
这种设置有一个严重的缺陷:它依赖于调用移动构造函数的编译器。由于复制省略规则,人们不能做这样的事情。
没有复制/移动构造函数怎么办?