简体   繁体   English

C ++:从void函数返回void函数的返回值

[英]C++: return the return value of a void function from a void function

I have several void functions (lets call them foo and bar) that share the same void function cleanup that, well, cleans up after them if they mess up: 我有几个void函数(让它们分别称为foo和bar),它们共享相同的void函数清理功能,如果它们弄乱了,则清理它们:

#include <iostream>

void cleanup() { std::cout << "doing cleanup" << std::endl; }

void foo(int & i) {
    if(i == 0) { return cleanup(); }
    --i;
    if(i == 0) { return cleanup(); }
    ++i;
}

void bar(int & i) {
    if(i == 0) { return cleanup(); }
    ++i;
    if(i == 0) { return cleanup(); }
    --i;
}

int main() {
    int i = 0;
    foo(i);
    bar(i);
    return 0;
}

cpp.sh happily compiles and runs the code. cpp.sh会愉快地编译并运行代码。

Thanks to the answer to this question I know that I can return an object of type void. 感谢这个问题的答案,我知道我可以返回void类型的对象。 But I don't know if it applies to returning void return values. 但是我不知道它是否适用于返回void返回值。

What do you think, does the code comply with the standard? 您认为代码是否符合标准?

And would you rather return dummy integers to make the code more readable? 您是否愿意返回伪整数以使代码更具可读性? Or would the useless return values make the code harder to read? 还是无用的返回值会使代码更难阅读?

edit: I feel like I need to add some clarification as to why eg 'cleanup(); 编辑:我觉得我需要添加一些澄清,为什么例如'cleanup(); return;' 返回;' is not a solution. 不是解决方案。 The actual code is more complex than the example and depending on where I leave the function some other stuff happens after the cleanup() call. 实际的代码比示例更复杂,并且取决于我离开函数的位置,在cleanup()调用之后还会发生其他事情。 'return cleanup();' “返回cleanup();” is just a convenient way of not putting all the stuff behind it in conditionals in instances where I can/have to leave immediately. 只是一种方便的方式,在我可以/必须立即离开的情况下,不将所有东西放在有条件的情况下。

From n4582 n4582

6.6.3 The return statement [stmt.return] 6.6.3 return语句[stmt.return]

Paragraph 2 第2段

The expr-or-braced-init-list of a return statement is called its operand. return语句的expr-or-braced-init-list称为其操作数。 A return statement with no operand shall be used only in a function whose return type is cv void, a constructor (12.1), or a destructor (12.4). 没有操作数的return语句只能在返回类型为cv void,构造函数(12.1)或析构函数(12.4)的函数中使用。 A return statement with an operand of type void shall be used only in a function whose return type is cv void. 操作数类型为void的return语句只能在返回类型为cv void的函数中使用。 A return statement with any other operand shall be used only in a function whose return type is not cv void; 带有任何其他操作数的return语句只能在返回类型不是cv void的函数中使用; the return statement initializes the object or reference to be returned by copy-initialization (8.5) from the operand. return语句将初始化对象或引用,该对象或引用将通过操作数的副本初始化(8.5)返回。

Questions: 问题:

But I don't know if it applies to returning void return values. 但是我不知道它是否适用于返回void返回值。

Yes its perfectly valid to return a void expression from a function that return void. 是的,从返回void的函数返回void表达式是完全有效的。 This becomes very handy in templated code so you don't have to special case void functions. 这在模板化代码中变得非常方便,因此您不必使用特殊情况的void函数。

What do you think, does the code comply with the standard? 您认为代码是否符合标准?

Yes absolutely. 是的,一点没错。

And would you rather return dummy integers to make the code more readable? 您是否愿意返回伪整数以使代码更具可读性? Or would the useless return values make the code harder to read? 还是无用的返回值会使代码更难阅读?

That's totally up to you and your aesthetics. 这完全取决于您和您的美学。 Does it make the code look more readable to you (or do you have coding guidelines that you need to follow). 它会使代码对您来说更具可读性(或者您有需要遵循的编码准则)。 Personally I would not return dummy values (as the user may expect some meaning from them). 我个人不会返回伪值(因为用户可能期望它们有一些含义)。

This is useful for perfect forwarding. 这对于完美转发很有用。 Imagine that you have a functor of type (template-parameter), so the return type can potentially be anything. 想象一下,您有一个类型为(模板参数)的函子,因此返回类型可能是任何东西。 This permission to return a value of type void allows you to call the functor and expose its return value to your caller, without having to write separate code for the case of no return value. 拥有返回void类型值的权限,您可以调用仿函数并将其返回值公开给调用者,而无需为无返回值的情况编写单独的代码。

template<typename Functor, typename... Args>
auto forward(Functor what_to_call, Args... args) -> decltype(what_to_call(std::forward<Args>(args)...))
{
    return what_to_call(std::forward<Args>(args)...);
}

That's already pretty messy, but if not for the ability to propagate void return types using the return keyword, you'd need two variations controlled by enable_if . 那已经很混乱了,但是如果不是要使用return关键字传播void返回类型的能力,则需要两个由enable_if控制的变体。

template<typename Functor, typename... Args>
auto forward(Functor what_to_call, Args... args) -> enable_if<is_same_type<decltype(what_to_call(std::forward<Args>(args)...)), void>::value, void>::type
{
    what_to_call(std::forward<Args>(args)...);
    return;
}

template<typename Functor, typename... Args>
auto forward(Functor what_to_call, Args... args) -> enable_if<!is_same_type<decltype(what_to_call(std::forward<Args>(args)...)), void>::value, decltype(what_to_call(std::forward<Args>(args)...))>::type
{
    return what_to_call(std::forward<Args>(args)...);
}

So, return function_returning_void(); 因此, return function_returning_void(); is designed for special circumstances where it is useful. 设计用于有用的特殊情况。 Don't feel that you have to return a dummy object of type void or any other type everywhere just because it is possible. 不必仅仅因为可能就必须返回void类型或其他任何类型的虚拟对象。 For example, don't do return void(); 例如,不要return void(); or return -1; return -1; when simply return; 简单return; will do. 会做。

What do you think, does the code comply with the standard? 您认为代码是否符合标准?

Yes, it does. 是的,它确实。 In a function returning void , you may use an expression in a return statement if the type of the expression is void . 在返回功能void ,你可以,如果表达式的类型是使用表达式return语句中void Which it is, if it is a call to a function that also returns void . 如果是对也返回void的函数的调用,则为后者。

And would you rather return dummy integers to make the code more readable? 您是否愿意返回伪整数以使代码更具可读性? Or would the useless return values make the code harder to read? 还是无用的返回值会使代码更难阅读?

I don't think dummy integers would make the code more readable. 我认为虚拟整数不会使代码更具可读性。 Programmers expect return values to be meaningful. 程序员期望返回值有意义。

What I think would be more readable, is to split the function call and the return to separate statements: 我认为更具可读性的是将函数调用和返回语句分开:

cleanup();
return;

Although I admit, that's entirely a matter of opinion. 尽管我承认,但这完全是见解。

If a function would return no value, it would be wiser to check if the function succeeded in doing what it had to do. 如果一个函数不返回任何值,那么检查该函数是否成功完成了它必须做的事情将更为明智。 A Little example: 一个小例子:

        bool foo()
        {
        if (DoSomeThing() == true)
        {
            return true;
        }
        else
        {
            return false;
        }

Then you could the return value of foo(): 然后,您可以返回foo()的返回值:

        if (!foo())
        {
            Console.WriteLine("foo returned false!");
        }

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

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