在纯C++中扩充类/应用方面(C++ 11)

Luc*_*Ian 2 c++ aop aspect c++11

假设我有一个班级:

class Widget {
public:
    void initialize() {
        // hurr-durr
    };

    int computeAnswer() {
        return -42;
    };

    std::string getQuestion() {
        return "The question";
    };
};
Run Code Online (Sandbox Code Playgroud)

它执行一些计算,可以做任何想做的事情.

现在我想增加它 - 应用一个方面,比如记录每个方法调用.

如果我手动实现,我将以这种方式实现所有方法:

  int LoggingWidget::computeAnswer(){
    log << 'Calling method computeAnswer';
    int result = Widget::computerAnswer();
    log << 'Result = ' << result;
    return result;
  }
Run Code Online (Sandbox Code Playgroud)

我希望解决方案尽可能通用(我不想手动转发所有调用),因此可能的用法可能包括其中一个(以可能的为准)

Widget* w = new LoggingWidget();  // either a class that inherits from Widget
                                  // and automatically forwards all calls.

Widget* w = new Logging<Widget>(); // or a template that does this.
Run Code Online (Sandbox Code Playgroud)

所以当我打电话的时候

 int result =  w.computeAnswer();
Run Code Online (Sandbox Code Playgroud)

将记录呼叫.也许新的省略号运算符(...)可以在这里派上用场?

Xeo*_*Xeo 6

这不是直接可行的,因为您无法检查类以查看它具有哪些成员.

但是,你可以做一些接近的事情:

Logging<Widget> w(widget);
w([&](Widget& w){
  return w.computeAnswer();
});
Run Code Online (Sandbox Code Playgroud)

Logging::operator()看起来如下:

/* somewhere in class: T wrapped; */

template<class F>
auto operator()(F&& f)
  -> decltype(f(wrapped))
{
  pre_log();
  auto&& result = f(wrapped);
  post_log(result);
  return result;
}
Run Code Online (Sandbox Code Playgroud)

对于完全通用的代码,它不会比这更好,因为C++没有(静态)反射.