类 Python 的 C 装饰器

新手上路,请多包涵

有没有办法像 Python 风格一样在 C++ 中装饰函数或方法?

 @decorator
def decorated(self, *args, **kwargs):
     pass

例如使用宏:

 DECORATE(decorator_method)
int decorated(int a, float b = 0)
{
    return 0;
}

或者

DECORATOR_MACRO
void decorated(mytype& a, mytype2* b)
{
}

可能吗?

原文由 Artem Selivanov 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 649
2 个回答

std::function 为我提出的解决方案提供了大部分构建块。

这是我提出的解决方案。

 #include <iostream>
#include <functional>

//-------------------------------
// BEGIN decorator implementation
//-------------------------------

template <class> struct Decorator;

template <class R, class... Args>
struct Decorator<R(Args ...)>
{
   Decorator(std::function<R(Args ...)> f) : f_(f) {}

   R operator()(Args ... args)
   {
      std::cout << "Calling the decorated function.\n";
      return f_(args...);
   }
   std::function<R(Args ...)> f_;
};

template<class R, class... Args>
Decorator<R(Args...)> makeDecorator(R (*f)(Args ...))
{
   return Decorator<R(Args...)>(std::function<R(Args...)>(f));
}

//-------------------------------
// END decorator implementation
//-------------------------------

//-------------------------------
// Sample functions to decorate.
//-------------------------------

// Proposed solution doesn't work with default values.
// int decorated1(int a, float b = 0)
int decorated1(int a, float b)
{
   std::cout << "a = " << a << ", b = " << b << std::endl;
   return 0;
}

void decorated2(int a)
{
   std::cout << "a = " << a << std::endl;
}

int main()
{
   auto method1 = makeDecorator(decorated1);
   method1(10, 30.3);
   auto method2 = makeDecorator(decorated2);
   method2(10);
}

输出:

 Calling the decorated function.
a = 10, b = 30.3
Calling the decorated function.
a = 10

附言

Decorator 提供了一个地方,您可以在其中添加除进行函数调用之外的功能。如果您想简单地传递到 std::function ,您可以使用:

 template<class R, class... Args >
std::function<R(Args...)> makeDecorator(R (*f)(Args ...))
{
   return std::function<R(Args...)>(f);
}

原文由 R Sahu 发布,翻译遵循 CC BY-SA 3.0 许可协议

您可以使用令牌粘贴预处理运算符## 获得这种类型的一些有限功能。请参阅 https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html 。困难在于,在 C 中,每个函数名都必须在链接时定义,因此函数不是可以像 Python 那样转换的对象。因此,在 Python 中,装饰器是有用且良好的风格,但在 C 中,如果有的话,应该谨慎使用这些技巧。

原文由 Paul Cornelius 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题