假设一个类存在如下:
class Foo
{
void do_after_something()
{
//some code here
return;
}
void do_something()
{
//some code here
return do_after_something(); //returning another (void) function
}
};
JAVA明显反对上述内容,Borland C ++编译器发出警告, MS VC ++没有抱怨。
我的问题是:从void函数返回逻辑上(理论上)是否正确?
return do_after_something();
而不是:
do_after_something();
return;
或是否依赖于所有实现(编译器/语言)?
答案 0 :(得分:8)
哲学上,你可以认为应该允许返回void
- 返回函数的结果,但遗憾的是,这不是这里的情况,至少对于Java来说。
对C ++有效。如果您尝试以下程序:
#include <iostream>
void xyzzy(void) {}
void plugh(void) { return xyzzy();}
int main() {
std::cout << "Hello\n";
plugh();
return 0;
}
它会正常工作。
详情见ISO C++11 6.6.3 /3
:
表达式为
void
的return语句只能用于返回类型为cv void
的函数;在函数返回其调用者之前计算表达式。
因此,如果您认为void
不是实际类型,而是将某些内容视为缺席,则认为Java方式是正确的,这同样有效。例如,当你有:
int xyzzy(void) { return 42; }
在C中,您不必强制提供正确(非)类型的参数,例如:
void plugh;
int twisty = xyzzy(plugh);
同上,C ++方式也是正确的,但以不同的方式 - 语言就是它们。
答案 1 :(得分:2)
我认为它应该被允许并被认为在所有语言中都有效。如果您有一个返回类型为void
的函数,并且您返回类型为void
的表达式的结果(例如调用另一个void
函数),那么您已经满意了约束
在C中执行此操作并不被认为有用(尽管我认为可能允许),因为没有理由需要它。你随时都可以:
return someVoidFn();
您始终可以将其翻译为:
someVoidFn();
return;
获得完全相同的效果。
但是,在C ++和Java中,返回void
函数确实有用,因为这些语言有模板和泛型。考虑这个(不是很有用)Java类:
class NestedIdentity<T> {
T run(int i, T value) {
if (i == 0) return value;
return run(i - 1);
}
}
它的run
方法在调用给定次数后返回传递给它的值。我知道,没有意义,对吧?但重要的是T
可能无效。你可以这样做:
NestedIdentity<Void> nest = new NestedIdentity<Void>();
nest(5, null);
这个有效。在Java中,Void
(注意大小写)实例化一个类似void
类型的泛型,其唯一值为null
。如果Java不允许在void
方法中返回void
表达式,那么使用void实例化泛型就必须是编译时错误。
答案 2 :(得分:1)
在C ++ 11中,它可行且合法。您可以从其他void函数返回void函数。 参考C ++编程语言第12章,Bjarne Strousstrup