从C++函数立即返回,不使用预处理器或后藤[已关闭]

waxmsbnn  于 2023-02-26  发布在  其他
关注(0)|答案(4)|浏览(145)

已关闭。此问题为opinion-based。当前不接受答案。
**想要改进此问题吗?**请更新此问题,以便editing this post可以用事实和引文来回答。

昨天关门了。
Improve this question
我有许多方法,有重复的代码,如下面。有没有办法取代它与一些一个函数调用,将获得结果的方法和返回。

TaskResult RunSomeTask()
{
    TaskResult& res = GetTaskResult();
    if (res.status == STILL_RUNNING)
        return res;

    // ... Proceed with new task

}

使用预处理器宏很容易实现,但宏被认为是不良的编码风格。

#define RETURN_WHEN_STILL_RUNNING   TaskResult& res = GetTaskResult(); \
                                    if (res.status == STILL_RUNNING) return res;

在C17或C20中有没有其他的解决方案?

5ssjco0h

5ssjco0h1#

那些认为宏是糟糕的编码风格的人,认为这是 * 因为他们让你这样做,他们认为这是糟糕的编码风格 *。如果你用不同的方式做同样的事情,他们也会说这是糟糕的编码风格。
另外,也没有别的办法。所以用宏吧。

chhqkbe1

chhqkbe12#

您最终要做的是两件事:隐藏return语句并隐藏变量声明(大概res稍后将在函数中使用;如果没有,你应该把它放在一个块作用域中)。没有一个C++构造可以做这两件事。函数不能为它们的调用者声明变量,也不能使它们的调用者返回(在throw之外,但是抛出异常作为控制流通常是个坏主意)。
所以这里唯一的解决方案是宏。这被认为是不好的形式,因为它使不了解函数的用户不清楚函数中的控制流是什么。名称RETURN_WHEN_STILL_RUNNING至少暗示了return是隐藏的,但是它 * 不 * 暗示名称res现在是TaskResult&。所以如果用户看到res稍后在函数中被使用,他们将在不追踪宏的情况下混淆它来自哪里。
至少,将标识符的名称设置为宏参数。

2skhul33

2skhul333#

作为宏的替代方法,您可能需要考虑使用函数或类方法:

bool IsStillRunning (TaskResult * res) {
  *res = GetTaskResult();
  return res->status == STILL_RUNNING;
}

TaskResult RunSomeTask()
{
    TaskResult res;
    if (IsStillRunning(&res))
        return res;

    // ... Proceed with new task

    // Check again...
    if (IsStillRunning(&res))
        return res;

    // ... Continue with task

}
e4eetjau

e4eetjau4#

从更高的层次去做。

TaskResult RunSomeTask()
{
    TaskResult& res = GetTaskResult();
    if (res.status == STILL_RUNNING)
        return res;

    // ... Proceed with new task

}

template<class T> using Factory = std::function<void(T&)>;
template<class T> using Cache = Factory<T&>;
template<class T>
std::function<T()> CachedFactory = [](Factory<T> f, Cache<T&> c)->T {
  auto& r = c();
  if (IsReady(r))
    return r;
  f(r);
  return r;
};

所以现在你只需要定义IsReadyTaskResult上的含义,你就可以让你的RunSomeTaskCachedFactory生成。
在您的特定情况下,该高速缓存可能来自某个非全局对象,因此必须在那里进行一些调整。
但关键是你可以在函数构建块上做代数运算,而不是自己编写它们。

相关问题