C++:从 void 函数返回 void 函数的返回值[重复]

问题描述 投票:0回答:3

我有几个 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 愉快地编译并运行代码。

感谢这个问题的答案我知道我可以返回一个void类型的对象。但我不知道它是否适用于返回 void 返回值。

您认为该代码符合标准吗?

您愿意返回虚拟整数以使代码更具可读性吗?或者无用的返回值会使代码更难阅读?

编辑:我觉得我需要补充一些说明,例如为什么'清理();返回;'不是一个解决方案。实际的代码比示例更复杂,并且根据我离开函数的位置,在 cleanup() 调用之后还会发生一些其他事情。 '返回清理();'这只是一种方便的方法,在我可以/必须立即离开的情况下,不要将所有内容放在条件语句中。

c++ coding-style standards-compliance
3个回答
13
投票

来自n4582

6.6.3 return 语句[stmt.return]

第 2 段

return 语句的 expr-or-braced-init-list 称为它的操作数。不带操作数的 return 语句只能用在返回类型为 cv void 的函数、构造函数 (12.1) 或析构函数 (12.4) 中。 具有 void 类型操作数的 return 语句只能在返回类型为 cv void 的函数中使用。 具有任何其他操作数的 return 语句只能在返回类型不是 cv void 的函数中使用; return 语句初始化要通过复制初始化 (8.5) 从操作数返回的对象或引用。

问题:

但我不知道它是否适用于返回 void 返回值。

是的,从返回 void 的函数返回 void 表达式是完全有效的。这在模板化代码中变得非常方便,因此您不必使用特殊情况的 void 函数。

您认为该代码符合标准吗?

是的,绝对是。

您愿意返回虚拟整数以使代码更具可读性吗?或者无用的返回值会使代码更难阅读?

这完全取决于您和您的审美观。它是否使代码看起来更具可读性(或者您是否有需要遵循的编码指南)。就我个人而言,我不会返回虚拟值(因为用户可能期望从中得到一些含义)。


5
投票

这对于完美转发很有用。想象一下,您有一个类型(模板参数)的函子,因此返回类型可能是任何类型。返回

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)...);
}

这已经相当混乱了,但如果不是能够使用

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)...);
}

因此,

return function_returning_void();
是为特殊情况而设计的,它很有用。不要觉得你必须在任何地方返回
void
类型的虚拟对象或任何其他类型,只是因为它是可能的。例如,当只需
return void();
即可时,请勿执行
return -1;
return;


2
投票

您认为该代码符合标准吗?

是的,确实如此。在返回

void
的函数中,如果表达式的类型为
void
,则可以在 return 语句中使用表达式。确实如此,如果它是对也返回
void
的函数的调用。

您愿意返回虚拟整数以使代码更具可读性吗?或者无用的返回值会使代码更难阅读?

我认为虚拟整数不会使代码更具可读性。程序员期望返回值是有意义的。

我认为更具可读性的是,将函数调用和返回拆分为单独的语句:

cleanup();
return;

虽然我承认,但这完全是见仁见智的问题。

© www.soinside.com 2019 - 2024. All rights reserved.