gpt4 book ai didi

Test return value and return(测试返回值和返回)

转载 作者:bug小助手 更新时间:2023-10-26 20:17:55 28 4
gpt4 key购买 nike



This may be a silly question, but I am working if there is a concise way to test the return result of a function, and, if it fails to meet a condition, return that value (i.e., pass it on).

这可能是一个愚蠢的问题,但我正在努力,如果有一种简明的方法来测试函数的返回结果,如果它不满足条件,则返回该值(即,传递它)。


To address a possible question right now, yes, what I am looking for is similar to what exceptions offer. However, as an embedded developer, the overhead associated with exceptions (unfortunately) is too high a cost to pay.

现在来回答一个可能的问题,是的,我正在寻找的类似于例外提供的东西。然而,作为嵌入式开发人员,与异常相关的开销(遗憾的是)太高,无法支付。


For example,

例如,


enum class Status
{
OKAY,
ERROR1,
ERROR2,
ERROR3
};

Status foo1();
Status foo2();
Status foo3();

Status bar()
{
Status result;

result = foo1();
if (result != Status::OKAY) return result;

result = foo2();
if (result != Status::OKAY) return result;

result = foo3();
if (result != Status::OKAY) return result;

return Status::OKAY;
}

If I was just using a bool as the return value, a shorthand would be to write the following:

如果我只是使用布尔值作为返回值,一种速记方法是编写以下代码:


bool bar()
{
if (!foo1()) return false;
if (!foo2()) return false;
if (!foo3()) return false;

return true;
}

A side-effecting if clause like this is considered a code smell, but this seems more readable and concise to me than local variable assignments and tests.

像这样的副作用IF子句被认为是一种代码气味,但在我看来,这比局部变量赋值和测试更易读、更简洁。


Is there a a shorthand way to accomplish the same readability as the second example but with the same effect as the first example?

有没有一种快捷的方法可以实现与第二个示例相同的可读性,但具有与第一个示例相同的效果?


更多回答

operator bool() perhaps?

可能是操作符bool()?

If you do it this way you can collapse it to return foo1() && foo2() && foo3()

如果这样做,您可以折叠它以返回foo1()&&foo2()&&foo3()

Nothing comes to mind. FWIW, I consider the code in your first block to be idiomatic. If you tried to roll your own abstraction around this it might make it harder to maintain. I understand the frustration. Last time I worked with cURL I had methods that looked like this.

我什么也没想到。顺便说一句,我认为您第一个代码块中的代码是惯用的。如果您试图围绕这一点展开自己的抽象,可能会使维护变得更加困难。我理解这种挫折感。上次我使用cURL时,我的方法看起来是这样的。

result = foo1(); if (result != Status::OKAY) return result; can become if (auto ret = foo1(); ret != Status::OKAY) return ret; That can easily be wrapped in a macro if you want to condense down the syntax.

RESULT=foo1();If(Result!=Status::OK)Return Result;可以变成If(AUTO RET=foo1();ret!=Status::OK)Return ret;,如果您想精简语法,可以很容易地将其包装在宏中。

It was added in C++17

它是在C++17中添加的

优秀答案推荐

One way to do it is use a macro:

一种方法是使用宏:


enum class Status
{
OKAY,
ERROR1,
ERROR2,
ERROR3
};

#define CHECK_STATUS(call_site)\
do {\
Status result = call_site;\
if (result != Status::OKAY) return result;\
} while(0)

Status foo1();
Status foo2();
Status foo3();

Status bar()
{
CHECK_STATUS(foo1());

CHECK_STATUS(foo2());

CHECK_STATUS(foo3());

return Status::OKAY;
}

If you're puzzled by the do ... while(0), check this: do { ... } while (0) — what is it good for?

如果你对DO感到困惑..。While(0),检查这个:Do{...}While(0)-它有什么用处?



Since you're using C++17, you could write your bar() function like this, which isn't too bad, IMO:

由于您使用的是C++17,您可以这样编写bar()函数,这还不错,IMO:


Status bar() {
if (auto result = foo1(); result != Status::OKAY) return result;
if (auto result = foo2(); result != Status::OKAY) return result;
if (auto result = foo3(); result != Status::OKAY) return result;
return Status::OKAY;
}

Or, a lambda could come in handy as well. Although, I find it less appealing in this particular situation:

或者,Lambda也可以派上用场。不过,在这种特殊情况下,我觉得它不那么有吸引力:


Status bar() {
auto result = Status::OKAY;
auto const check = [&result](auto foo) -> bool
{ return (result = foo()) != Status::OKAY; };

if (check(foo1)) return result;
if (check(foo2)) return result;
if (check(foo3)) return result;
return result;
}

Maybe writing your own functor works better:

也许编写您自己的函数器效果更好:


Status bar() {
struct {
Status result;
bool operator()(Status (&foo)())
{ return (result = foo()) != Status::OKAY; };
} check{};

if (check(foo1)) return check.result;
if (check(foo2)) return check.result;
if (check(foo3)) return check.result;
return check.result;
}

Another way, is to take advantage of aggregate initialization, but this is stretching it a bit in terms of trickery.

另一种方法是利用聚合初始化,但这在诡计方面有点夸张。


Status bar() {
struct convert {
Status result;
explicit operator bool() const
{ return result != Status::OKAY; }
} check{};

if ((check = convert{foo1()})) return check.result;
if ((check = convert{foo2()})) return check.result;
if ((check = convert{foo3()})) return check.result;
return check.result;
}

Live example

现场示例



Based upon @NathanOliver's comment on my question, I wrote the following possible solution.

根据@NathanOliver对我的问题的评论,我写了以下可能的解决方案。


#include <iostream>

enum class Status
{
OKAY,
TOO_SMALL,
TOO_LARGE
};

bool operator!(Status s)
{
return s != Status::OKAY;
}

std::ostream& operator<<(std::ostream& os, Status s)
{
switch(s)
{
case Status::OKAY:
os << "OKAY";
break;
case Status::TOO_SMALL:
os << "TOO_SMALL";
break;
case Status::TOO_LARGE:
os << "TOO_LARGE";
break;
}

return os;
}

Status bar(int a)
{
if (a < 5) return Status::TOO_SMALL;
if (a > 10) return Status::TOO_LARGE;
else return {};
}

Status foo(int a)
{
if (auto r = bar(a); !r) return r;
if (auto r = bar(a + 1); !r) return r;
if (auto r = bar(a - 1); !r) return r;

return {};
}

void test(int a)
{
auto result = foo(a);
std::cout << "foo(" << a << ") -> " << result << std::endl;
}

int main()
{
test(8);
test(5);
test(10);

return 0;
}

I simplified the conditional testing of the enum by overloading the ! operator.

方法简化了枚举的条件测试!接线员。


更多回答

CHECK_STATUS -> RETURN_IF_STATUS_IS_NOT_OKAY.

Check_Status->Return_If_Status_is_Not_OK。

I've actually written something like this before in my code. I got shot down though because using a macro like this introduces a "dialect."

实际上,我以前在我的代码中写过类似的东西。然而,我被拒绝了,因为使用这样的宏会引入一种“方言”。

@PatrickWright It does, but are (simple) dialects a bad thing they are understood within a team? I'd say that if OP is coding by himself, this is probably fine. If they're part of a team, there should be a senior engineer that knows the commonly-accepted way to work in the team.

@PatrickWright确实如此,但是(简单的)方言在团队中被理解是一件坏事吗?我想说,如果OP是自己编码,这可能是好的。如果他们是一个团队的一部分,应该有一个高级工程师,知道在团队中普遍接受的工作方式。

This is a nice solution, but I'd declare your if init-expressions const: if(const auto result = ... since they are independent of each other and don't change. Declare an object const...

这是一个很好的解决方案,但是我要声明您的if init表达式const:if(const Auto Result=...因为它们是相互独立的,不会改变。声明对象常量...

@Casey Thanks for your suggestion, and I agree it's a good rule of thumb in general. However, for a single line if-statement, which I think are only good in combination with a single return-statement (one way to prevent to write deeper scopes), I think it adds little value. I would even argue that in some scenarios, like this one but with function parameters too, it's actually best omitted.

@Casey感谢你的建议,总的来说,我同意这是一个很好的经验法则。然而,对于单行if-语句,我认为它只有与单个返回语句(防止编写更深层次的作用域的一种方法)结合使用时才有好处,我认为它没有什么价值。我甚至会争辩说,在某些场景中,比如这个场景,但也有函数参数,实际上最好省略它。

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