简体   繁体   English

如何使 function 参数在 C++ 中单行传递之前和之后执行某些操作

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM