我有几个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愉快地编译并运行代码。
感谢the answer to this question我知道我可以返回void类型的对象。但我不知道它是否适用于返回空值返回值。
您如何看待代码是否符合标准?
您是否宁愿返回虚拟整数以使代码更具可读性?或者无用的返回值会使代码难以阅读吗?
编辑:我觉得我需要添加一些说明,例如为什么&#39;清理();返回;&#39;不是解决方案。实际代码比示例更复杂,并且取决于我离开函数的位置,在cleanup()调用之后会发生其他一些事情。 &#39;返回清理();&#39;在我可以/必须立即离开的情况下,只是一种方便的方法,不会将所有东西放在条件中。
答案 0 :(得分:5)
第2段
return语句的expr-or-braced-init-list称为其操作数。不带操作数的return语句只能用于返回类型为cv void的函数,构造函数(12.1)或析构函数(12.4)。 具有void类型的操作数的return语句只能在返回类型为cv void的函数中使用。具有任何其他操作数的return语句只能在返回类型不是cv的函数中使用无效; return语句初始化要从操作数复制初始化(8.5)返回的对象或引用。
问题:
但我不知道它是否适用于返回的返回值。
是的,从返回void的函数返回void表达式是完全有效的。这在模板化代码中变得非常方便,因此您不必使用特殊情况的void函数。
您如何看待代码是否符合标准?
是绝对的。
您是否宁愿返回虚拟整数以使代码更具可读性?或者无用的返回值会使代码难以阅读吗?
这完全取决于你和你的美学。它是否使代码看起来更具可读性(或者您是否需要遵循编码指南)。就个人而言,我不会返回虚拟值(因为用户可能期望从中获得某些意义)。
答案 1 :(得分:2)
这对于完美转发非常有用。想象一下,你有一个类型(模板参数)的仿函数,所以返回类型可能是任何东西。这种返回类型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 :(得分:2)
您如何看待代码是否符合标准?
是的,确实如此。在返回void
的函数中,如果表达式的类型为void
,则可以在return语句中使用表达式。它是什么,如果它是对函数的调用也返回void
。
您是否宁愿返回虚拟整数以使代码更具可读性?或者无用的返回值会使代码难以阅读吗?
我不认为虚拟整数会使代码更具可读性。程序员期望返回值有意义。
我认为更具可读性的是分割函数调用和返回单独的语句:
cleanup();
return;
虽然我承认,这完全是一个意见问题。
答案 3 :(得分:0)
如果一个函数没有返回任何值,那么检查函数是否成功完成它必须做的事情会更明智。一个小例子:
bool foo()
{
if (DoSomeThing() == true)
{
return true;
}
else
{
return false;
}
然后你可以返回foo()的返回值:
if (!foo())
{
Console.WriteLine("foo returned false!");
}