简体   繁体   English

如何从单个 C++ 返回语句返回多个值中的一个?

[英]How to return one out of multiple values from a single C++ return statement?

return a or b or c or d;

That statement returns either true or false in C++, and I know the reason for this.该语句在 C++ 中返回truefalse ,我知道其中的原因。

But I need a workaround so that I can return the first non-zero value via that return statement (or something similar) like it happens in Python .但我需要一个解决方法,以便我可以通过该 return 语句(或类似的东西)返回第一个非零就像在 Python 中发生的那样

I am not looking for conditional statements as it looks untidy sometimes .我不是在寻找条件语句,因为它有时看起来不整洁。

Basically, can the following code be shortened via a macro or something else?基本上,可以通过宏或其他方式缩短以下代码吗?

int fun(int a, int b, int c, int d)
{
    return a ? a : b ? b : c ? c : d;
}

The task can be accomplished by using the necessary function in the return statement.该任务可以通过在返回语句中使用必要的 function 来完成。

For example, instead of a macro, I used a templated function which accepts the parameters in std::initializer_list :例如,我使用了模板化的 function 而不是宏,它接受std::initializer_list中的参数

template <typename T>
T OR(const std::initializer_list<T>& args)
{
    for (const T& arg : args)
        if (arg)
            return arg;
    return T{};
}

It can be used as follows for the given problem:对于给定的问题,它可以按如下方式使用:

return OR({a, b, c, d});

The problem in that link can also be solved in this way:该链接中的问题也可以通过这种方式解决:

return OR({(m + s - 1) % n, n});

Note that it depends on the implicit boolean conversion of a given type T .请注意,它取决于给定类型T的隐式 boolean 转换。 So, for example, an empty std::string is not false .因此,例如, 一个空的std::string不是false Also, a user-defined type should have operator bool() const in order to comply with this workaround.此外,用户定义的类型应具有operator bool() const以符合此解决方法。

PS While I was trying to ask my mistake in a variadic template solution in the question, I discovered this solution myself:P PS 当我试图在问题的可变参数模板解决方案中询问我的错误时,我自己发现了这个解决方案:P

Note:笔记:

See this answer to know the limitations of this way when working with more complex designs.查看答案以了解这种方式在处理更复杂的设计时的局限性。

I would write the function like this:我会这样写 function:

int fun(int a, int b, int c, int d) {
    if (a) return a;
    else if (b) return b;
    else if (c) return c;
    return d;
}

It is clean and short.它干净而简短。 I could stop here, but lets explore what can be done...我可以在这里停下来,但让我们探索可以做什么......

There exists an algorithm that already almost does what you want.存在一种几乎可以满足您要求的算法。 A slight modification of the solution in this answer :对该答案中的解决方案稍作修改:

#include <algorithm>
#include <initializer_list>

template <typename T>
T first_non_zero_or_zero(const std::initializer_list<T>& args)
{
    auto it = std::find_if_not(args.begin(),args.end(),[](auto v){ return v==0;});    
    return (it != args.end()) ? *it : 0;
}

The drawback of using a function for boolean expressions is no short-cuirciting.将 function 用于 boolean 表达式的缺点是没有短路。 If you call the function via:如果您通过以下方式拨打 function:

auto x = first_non_zero_or_zero( { foo(), expensive_function() });

Then expensive_function must be called, no matter what foo returns.然后必须调用expensive_function ,无论foo返回什么。 The way to restore the ability to short-circuit is to pass callables instead, that would be恢复短路能力的方法是传递可调用对象,那将是

template <typename F>
auto first_non_zero_or_zero(F f){ return f();}

template <typename First,typename...F>
auto first_non_zero_or_zero(First f,F... others){    
    if (auto temp = f()) return temp;
    return first_non_zero_or_zero(others...);
}

int foo(){ return 0;}
int expensive_function(){ return 42;}

int main()
{
    std::cout << first_non_zero_or_zero(foo,expensive_function);
    return 0;
}

However, this will make calls unnecessarily verbose when called with simple int s, as you need to wrap them in a callable:但是,当使用简单的int调用时,这会使调用不必要地冗长,因为您需要将它们包装在可调用对象中:

int fun(int a,int b,int c) {
    first_non_zero( [](){ return a;},
                    [](){ return b;},
                    [](){ return c;})
}

Conclusion: Don't make things more complicated than necessary.结论:不要让事情变得不必要的复杂。 Functions should do one thing.函数应该做一件事。 The one thing your fun does is to return the first non-zero of 4 integers and a if-else is the most simple way to get that done.你的fun所做的一件事是返回 4 个整数中的第一个非零值,而if-else是完成该操作的最简单方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM