当前调用一个复杂的“计算器”,如下所示:
result = calculator.calc(a, b, extra);
不幸的是,有时可能会由于服务器上发生不相关的更改而失败。与不同部门同步很困难——重试更容易......
为此,我实现了一个
retry
lambda 函数:
auto retry = [](const auto& func, auto... args) {
int attempts = 5;
for (;;) try {
return func(args...);
}
catch (const std::system_error& e) {
/* Don't retry in case of a system_error */
throw;
}
catch (const exception& e) {
if (attempts-- == 0)
throw; /* Give up and rethrow */
Logging::log(Logging::Level::Warning,
"%s. Retrying %d more times.", e.what(), attempts);
sleep(2);
}
};
上面的代码可以编译,但是,当我尝试使用它时:
result = retry(calculator.calc, a, b, extra);
我从 clang 中收到错误:
reference to non-static member function must be called
。 GNU c++ 用 invalid use of non-static member function
标记同一行。
确实,
calc()
是Calculator类的非静态方法。
我将如何使用我的新 lambda?
在 lambda 中,将
func(args...)
替换为 std::invoke(func, args...)
。现在你的 lambda 支持成员函数指针。
传递成员函数指针,语法为
result = retry(&Calcuator::calc, calculator, a, b, extra);
其中
Calculator
是 calculator
的类类型。需要额外的参数来调用类的指定对象/实例上的非静态成员函数。 std::invoke
知道如何自动处理。