请考虑以下代码段:
void Foo()
{
// ...
}
void Bar()
{
return Foo();
}
在C ++中使用上述内容的正当理由是什么,而不是更常见的方法:
void Foo()
{
// ...
}
void Bar()
{
Foo();
// no more expressions -- i.e., implicit return here
}
答案 0 :(得分:16)
在您的示例中可能没用,但在某些情况下,很难在模板代码中处理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。
答案 1 :(得分:9)
这是一个相当无用的结构,除非与模板一起使用,否则没有用处。也就是说,如果您定义了模板函数,它返回的值可能是'void'。
答案 2 :(得分:7)
您可以在通用代码中使用它,其中Foo()的返回值未知或可能会更改。考虑:
template<typename Foo, typename T> T Bar(Foo f) {
return f();
}
在这种情况下,Bar对void有效,但如果返回类型发生更改,则也有效。但是,如果它只是调用f,那么如果T是非空的,那么这个代码就会破坏。使用return f();语法保证保存Foo()的返回值(如果存在),AND允许void()。
此外,明确返回是一个很好的习惯。
答案 3 :(得分:4)
模板:
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)
在被要求换func2
时将无效。
答案 4 :(得分:0)
我能想到的唯一原因是,如果您在交换机中有一长串return Foo();
语句,并希望使其更紧凑。
答案 5 :(得分:0)
原因是像math.h一样返回内存。 math.h没有void,也没有空参数。在许多需要记忆的实际情况中。
答案 6 :(得分:0)
可能是Foo()
最初返回一个值,但后来更改为void
的情况,而更新它的人只是不太清楚。