gpt4 book ai didi

c++ - 如何将 Action 委托(delegate)给函数返回?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:26:25 25 4
gpt4 key购买 nike

问题

我到处都出现以下简单情况。大量请求使用这样的函数签名到达设备:

Err execute( const ICommandContext &context, 
const RoutineArguments &arguments,
RoutineResults &results)

本质上有一个请求处理服务器,它将为具有这些签名的各种请求类型调用此执行函数。在出现错误的情况下,我们有 2 个返回路径。

  1. Err 输出类型(认为它等同于 int),用于通知服务器或系统出现了与系统,而不是请求。在处理用户请求之前,它始终排在函数的顶部。
  2. RoutineResults 提供了一个setStatus函数,可以用来将请求失败的信息返回给客户端。

由于这个原因,我们弹出了很多这种类型的代码:

// Failure due to request
Err error = someFunctionCall(clientInput);
if (!error.success()) {
results.setStatus(error); // Inform the client of the error
return SUCCESS; // Inform the system that we are all good
}

我们有一个特定的请求类型,它包含大约 15 个参数,这些参数在系统中传入和传出。我们在概念上需要 15 个这样的 if error do 集,这看起来很浪费。如果我们需要检查并更改返回方式的任何内容,它也很容易出错。 我们如何有效地委托(delegate) setStatus 并返回到函数中只需要发生一次的少量代码?

宏观解决方案

c 系统可能会用一个宏来解决这个问题,比如:

#define M_InitTry Err error
#define M_Try(statement) if (!(error = statement).success()) { goto catch_lab; }
#define M_Catch catch_lab: if (!error.successs())
#define M_Return return error

可以这样使用:

Err execute( const ICommandContext &context, ...) {
M_InitTry;

...

M_Try(someFunctionCall(clientInput));
M_Try(someFunctionCall(otherClientInput));
...

M_Catch {
// Other specific actions for dealing with the return.
results.setStatus(error);
error = SUCCESS;
}
M_Return;
}

这很好地清理了代码,但对于 goto 来说并不是特别好。如果定义可能被 goto 跳过的变量,将会导致问题。

委托(delegate)解决方案

我正在尝试考虑更多的 C++,所以我认为 RAII 类型委托(delegate)可能会有所帮助。像这样的东西:

class DelegateToFunctionEnd {

typedef std::function<void(void)> EndFunction;

public:
DelegateToFunctionEnd(EndFunction endFunction) : callAtEnd(endFunction) { }

~DelegateToFunctionEnd() {
callAtEnd();
}

private:
EndFunction callAtEnd;
};

非常简单,它通过在析构函数中实现操作来执行操作委托(delegate),直到函数返回。你可以像这样使用它:

Err execute( const ICommandContext &context, ...) {
Err error;
DelegateToFunctionEnd del(std::bind(&RoutineResults::setStatus, &results, std::cref(error)));

error = someFunctionCall(clientInput));
if (error) return SUCCESS;

...
}

Live example.这个解决方案看起来不错,但有几个问题:

  1. 不清楚发生了什么。
  2. 正确设置error更容易出错。
  3. 您仍然需要大量的 if 语句来处理返回。
  4. 配置终止操作的能力不是很好。
  5. 如果用户在函数返回时没有仔细考虑项目的销毁顺序是危险的。

更好的解决方案?

这一定是经常出现的问题。是否有一个通用解决方案可以提供此集合的干净委托(delegate)并返回类型操作?


我在下面有一些不幸的限制。不要让这些阻止您回答,因为它可能对 future 的人有所帮助。

  1. 我正在开发一个 c++03 受限系统。我们有 boost,但没有 c++11。
  2. 嵌入式系统,我们有关于异常和内存分配的愚蠢规则。

最佳答案

如果错误状态代码很麻烦,您应该考虑使用异常。也就是说,更改您的函数的 API

  • 所以他们保证成功作为后置条件
  • 在失败时抛出一个合适的std::exception

如果您这样做,就不可能“忘记”检查状态代码。如果您选择不处理错误情况,低级代码抛出的异常会自动向上渗透。如果出现以下情况,您只需要捕获一个低级异常

  • 您需要在发生错误时进行一些手动回滚或重新分配,并且 RAII 是不切实际的。在这种情况下,您将重新抛出异常。
  • 您想使用抛出的嵌套异常将低级异常消息或异常类型转换为高级消息。

关于c++ - 如何将 Action 委托(delegate)给函数返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51517670/

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