我正在编写一个提供类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;
};
bool calc
会跟踪此声明是否需要评估。然后fuse
操作带有一个可变参数块:
struct fuse {
template<typename... Bs>
fuse(Bs&&... bs) {
// Recurse and evaluate...
}
};
这个设置有一个严重的缺陷:它依赖于编译器调用移动构造函数。由于复制省略规则,不能做这样的事情。
如何在没有复制/移动构造函数的情况下执行此操作?