[英]How to make a function argument do something before and after being passed in one-liner in C++
I would like to make an object do something before and after being passed as an argument into a function, but (1) without modifying the function and (2) in a neat way.我想让 object 在作为参数传递到 function 之前和之后做一些事情,但是(1)不修改 function 和(2)以简洁的方式。
Here is the first one that comes to my mind, with RAII.这是我想到的第一个,RAII。 However, I think the expression (x.lock(), x)
is ugly.但是,我认为表达式(x.lock(), x)
很难看。
I think there would definitely be a good solution, but I can't think of one.我认为肯定会有一个很好的解决方案,但我想不出一个。
#include <iostream>
using namespace std;
// I can change this class
struct RAII {
RAII() {
cout << "do sth globally" << endl;
}
~RAII() {
cout << "revert it" << endl;
}
};
class A {
public:
// I can change this function, too.
auto lock() {
return RAII();
}
};
void f(const A& obj) {
cout << "a function that I can't change" << endl;
}
int main() {
A x;
// I think the expression is somewhat ugly.
// Can I make this a more neat one-liner, like f(x.locked())?
f((x.lock(), x));
}
The output is the same as below. output 与以下相同。
do sth globally
a function that I can't change
revert it
You cannot do it when the function and call are:当 function 和呼叫是:
void f(const A& obj);
f(x);
and you are not allowed to change these.你不能改变这些。 There is no way to make the object aware of a reference being taken.没有办法让 object 知道正在采用的参考。
You can however, call a different function:但是,您可以调用不同的 function:
void f2(const A& obj) {
obj.before();
f(obj);
obj.after();
}
f2(x); // <- one line
With RAII that would be something along the line of有了 RAII,这将是类似的东西
struct helper {
const A& obj;
helper(const A& obj) : obj(obj) { before(obj); }
~helper() { after(obj); }
};
void f2(const A& a) {
helper h{a};
f(a);
}
Wrapping the function doesn't work for you?包装 function 对你不起作用?
#include <iostream>
class A {
public:
void preProc() const {
std::cout<<"Pre-proc\n";
}
void postProc() const {
std::cout<<"Post-proc\n";
}
};
struct RAII {
explicit RAII(const A& a): a_(a){
a_.preProc();
}
~RAII() {
a_.postProc();
}
private:
const A& a_;
};
void f(const A& a){
}
void fWrap(const A& a){
RAII r(a);
f(a);
}
int main() {
A a;
fWrap(a);
}
Obviously this is just more convenience over just writing a.preProc()
and a.postProc()
every time before the function call.显然,这比每次在 function 调用之前编写a.preProc()
和a.postProc()
更方便。 If it's just a single instance, the entire RAII
class can just be removed!如果只是单个实例,整个RAII
class 就可以去掉!
Edit:编辑:
My motivation for RAII was perhaps a bit myopic.我对 RAII 的动机可能有点短视。 As @largest_prime_is_463035818 rightly adds, if f()
actually threw an exception, the ~RAII()
would be called, allowing cleanup of anything that had been set up in the a.preProc()
which isn't available in the vanilla function-wrap scenario.正如@largest_prime_is_463035818 正确补充的那样,如果f()
实际上抛出了异常,则~RAII()
将被调用,从而允许清理在a.preProc()
中设置的任何内容,而这些内容在 vanilla 函数中不可用 -包装场景。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.