我最近遇到了一个案例,我有一个 const 成员函数执行操作并返回结果。例如,
class Foo { ...
Foo add(Foo const & x) const;
}
但是其他人无意中调用了它,就像它正在更新this
对象一样(忽略结果):
Foo a = ...;
Foo b = ...;
a.add(b);
(这个错误实际上是由不完美的重构引入的。)
有没有办法让上面的最后一行触发错误或警告?下一个最好的事情是运行时捕获,这主要由以下模板解决。但是,它会破坏返回值优化,如计数器结果所示。
template<typename T>
class MustTake {
T & obj;
bool took;
public:
MustTake(T o) : obj(o), took(false) {}
~MustTake() { if (!took) throw "not taken"; }
operator T&() { took = true; return obj;}
};
struct Counter {
int n;
Counter() : n(0) {}
Counter(Counter const & c) : n(c.n+1) {}
~Counter() {}
};
Counter zero1() {
return Counter();
}
MustTake<Counter> zero2() {
return Counter();
}
int main() {
Counter c1 = zero1();
printf("%d\n",c1.n); // prints 0
Counter c2 = zero2();
printf("%d\n",c2.n); // prints 1
zero1(); // result ignored
zero2(); // throws
return 0;
}
我想我可以通过使用宏来改善效率低下,以便 MustTake<> 仅用于调试并且对发布无操作。
我正在寻找一个编译时解决方案。如果做不到这一点,我正在寻找最佳的运行时解决方案。