考虑以下代码段:
void Foo()
{
// ...
}
void Bar()
{
return Foo();
}
在 C++ 中使用上述方法而不是更常见的方法的正当理由是什么:
void Foo()
{
// ...
}
void Bar()
{
Foo();
// no more expressions -- i.e., implicit return here
}
在您的示例中可能没有用,但是在某些情况下很难void
在模板代码中处理,我希望这条规则有时会有所帮助。非常人为的例子:
#include <iostream>
template <typename T>
T retval() {
return T();
}
template <>
void retval() {
return;
}
template <>
int retval() {
return 23;
}
template <typename T>
T do_something() {
std::cout << "doing something\n";
}
template <typename T>
T do_something_and_return() {
do_something<T>();
return retval<T>();
}
int main() {
std::cout << do_something_and_return<int>() << "\n";
std::cout << do_something_and_return<void*>() << "\n";
do_something_and_return<void>();
}
请注意,只main
需要处理这样一个事实,即在这种void
情况下没有任何东西可以从retval
. 中间函数do_something_and_return
是通用的。
当然,这只能让你到目前为止 - 如果do_something_and_return
想要,在正常情况下,存储retval
在一个变量中并在返回之前对它做一些事情,那么你仍然会遇到麻烦 - 你必须专门(或重载do_something_and_return
)空白。
这是一个相当无用的结构,没有任何用途,除非它与模板一起使用。也就是说,如果您定义了返回值可能为“void”的模板函数。
您将在通用代码中使用它,其中 Foo() 的返回值未知或可能更改。考虑:
template<typename Foo, typename T> T Bar(Foo f) {
return f();
}
在这种情况下,Bar 对 void 有效,但在返回类型更改时也有效。但是,如果它只是调用 f,那么如果 T 是非空的,那么这段代码就会中断。使用返回 f(); 如果存在 Foo() 的返回值,则语法保证保留该返回值,AND 允许 void()。
此外,明确返回是一个好习惯。
模板:
template <typename T, typename R>
R some_kind_of_wrapper(R (*func)(T), T t)
{
/* Do something interesting to t */
return func(t);
}
int func1(int i) { /* ... */ return i; }
void func2(const std::string& str) { /* ... */ }
int main()
{
int i = some_kind_of_wrapper(&func1, 42);
some_kind_of_wrapper(&func2, "Hello, World!");
return 0;
}
如果无法返回 void,return func(t)
则模板中的 the 在被要求 wrap 时将不起作用func2
。
原因是像 math.h 一样返回内存总是返回。math.h 没有 void 也没有空参数。有许多实际情况需要记忆。
可能是Foo()
最初返回一个值,但后来改为void
,更新它的人只是没有想清楚。
我能想到的唯一原因是,如果您return Foo();
在 switch 中有很长的语句列表并希望使其更紧凑。