Consider the following snippet:
void Foo()
{
// ...
}
void Bar()
{
return Foo();
}
What is a legitimate reason to use the above in C++
This is a rather useless construction that serves no purpose, unless it is used with templates. That is, if you have defined template functions that returns a value that may be 'void'.
The reason is returning memory like math.h always returns. math.h has no void and no empty arguments. There are many practical situations where you need memory.
Could be a case where Foo()
originally returned a value, but was later changed to void
, and the person who updated it just didn't think very clearly.
The only reason I can think of is if you had a long list of return Foo();
statements in a switch and wanted to make it more compact.
You would use it in generic code, where the return value of Foo() is unknown or subject to change. Consider:
template<typename Foo, typename T> T Bar(Foo f) {
return f();
}
In this case, Bar is valid for void, but is also valid should the return type change. However, if it merely called f, then this code would break if T was non-void. Using the return f(); syntax guarantees preservation of the return value of Foo() if one exists, AND allows for void().
In addition, explicitly returning is a good habit to get into.
Probably no use in your example, but there are some situations where it's difficult to deal with void
in template code, and I expect this rule helps with that sometimes. Very contrived example:
#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>();
}
Note that only main
has to cope with the fact that in the void
case there's nothing to return from retval
. The intermediate function do_something_and_return
is generic.
Of course this only gets you so far - if do_something_and_return
wanted, in the normal case, to store retval
in a variable and do something with it before returning, then you'd still be in trouble - you'd have to specialize (or overload) do_something_and_return
for void.