gpt4 book ai didi

c++ - 通用指数退避重试机制 C++11

转载 作者:行者123 更新时间:2023-11-30 03:24:03 25 4
gpt4 key购买 nike

我用 C++11 编写了一个通用的指数退避重试循环。我正在使用 std::function 将可调用传递给重试循环。如果 isRetriable 函数返回 true,将重试 callable

#include <algorithm>
#include <cassert>
#include <chrono>
#include <functional>
#include <iostream>
#include <thread>

constexpr int64_t max_backoff_milliseconds = 30000; // 30 seconds

template <class R, class... Args>
R Retry(int max_retry_count, int64_t initial_dealy_milliseconds,
const std::function<bool(R)> &isRetriable,
const std::function<R(Args...)> &callable, Args &&... args)
{
int retry_count = 0;
while (true) {
auto status = callable(std::forward<Args>(args)...);
if (!IsRetriable(status)) {
return status;
}

if (retry_count >= max_retry_count) {
// Return status and abort retry
return status;
}
int64_t delay_milliseconds = 0;
if (initial_dealy_milliseconds > 0) {
delay_milliseconds =
std::min(initial_dealy_milliseconds << retry_count,
max_backoff_milliseconds);
}
std::cout << "Callable execution failed. Retry Count:"
<< retry_count + 1 << std::endl;
std::this_thread::sleep_for(
std::chrono::milliseconds(delay_milliseconds));
retry_count++;
}
}

bool isRetriable(int status) {
if (status == 5)
return true;
return false;
}

int foo(int x, int y) {
static int a = 1;
a += (x + y);
return a / 6;
}

int main() {
auto result = Retry(1000, 100, isRetriable, foo, 1, 3);
std::cout << result << std::endl;
return 0;
}

当我编译它时,出现以下错误:

prog.cpp: In function ‘int main()’:
prog.cpp:50:71: error: no matching function for call to ‘Retry(int,
int, bool (&)(int), int (&)(int, int), int, int)’
auto result = Retry<int, int, int>(1000, 100, isRetriable, foo, 1, 3);
^
prog.cpp:11:3: note: candidate: template<class R, class ... Args> R
Retry(int, int64_t, const std::function<bool(R)>&, const
std::function<_Res(_ArgTypes ...)>&, Args&& ...)
R Retry(int max_retry_count,
^~~~~
prog.cpp:11:3: note: template argument deduction/substitution failed:
prog.cpp:50:71: note: mismatched types ‘const
std::function<int(_ArgTypes ...)>’ and ‘int(int, int)’
auto result = Retry<int, int, int>(1000, 100, isRetriable, foo, 1, 3);
^

有人可以向我解释为什么会出现此错误吗?

最佳答案

我确定有一个很好的拷贝,但是......

这是一个较短的复制品:

template <typename T> void foo(std::function<bool(T)> ) { }
bool maybe(int ) { return false; }

foo(maybe); // error: no matching function call to 'foo(bool (&)(int))'

您可能会问 - 什么?! maybe 可以用一些 T 调用的东西返回 bool .但这不是模板推导的工作方式。为了推导std::function<bool(T)>反对一个论点,那个论点需要是一个 std::function . maybe不是 std::function ,它只是一个函数,所以推导失败。任何一种具有不同类型表达式的推导也会失败:

foo([](int ) { return true; }); // also error

基本上,试图推断一个std::function几乎总是错误的做法。首先,这是错误的,因为它行不通。其次,它是错误的,因为即使它确实有效,您也会在您可能不需要它的上下文中招致类型删除。

您要做的是推导任意可调用项,然后根据这些可调用项确定这些其他参数是什么。 callable 的返回类型这正是您调用 callable 时得到的结果与 Args... ,并且您想确保 isRetriable是该类型的谓词。

一种方法是:

template <typename Predicate, typename Callable, typename... Args,
// figure out what the callable returns
typename R = std::decay_t<std::invoke_result_t<Callable&, Args...>>,
// require that Predicate is actually a Predicate
std::enable_if_t<
std::is_convertible_v<std::invoke_result_t<Predicate&, R>, bool>,
int> = 0>
R Retry(int max_retry_count, int64_t initial_dealy_milliseconds,
Predicate&& isRetriable,
Callable&& callable,
Args&&... args)
{
// ....
}

关于c++ - 通用指数退避重试机制 C++11,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50049996/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com