Returning From a Void Function in C++

2020-02-26 07:19发布

Consider the following snippet:

void Foo()
{
  // ...
}

void Bar()
{
  return Foo();
}

What is a legitimate reason to use the above in C++ as opposed to the more common approach:

void Foo()
{
  // ...
}

void Bar()
{
  Foo();

  // no more expressions -- i.e., implicit return here
}

标签: c++ return void
7条回答
看我几分像从前
2楼-- · 2020-02-26 07:49

Templates:

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;
}

Without being able to return void, the return func(t) in the template would not work when it was asked to wrap func2.

查看更多
ゆ 、 Hurt°
3楼-- · 2020-02-26 07:50

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.

查看更多
Rolldiameter
4楼-- · 2020-02-26 07:52

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.

查看更多
太酷不给撩
5楼-- · 2020-02-26 07:54

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'.

查看更多
成全新的幸福
6楼-- · 2020-02-26 08:09

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.

查看更多
▲ chillily
7楼-- · 2020-02-26 08:13

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.

查看更多
登录 后发表回答