12

考虑以下代码段:

void Foo()
{
  // ...
}

void Bar()
{
  return Foo();
}

在 C++ 中使用上述方法而不是更常见的方法的正当理由是什么:

void Foo()
{
  // ...
}

void Bar()
{
  Foo();

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

7 回答 7

18

在您的示例中可能没有用,但是在某些情况下很难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)空白。

于 2010-08-08T15:29:26.437 回答
9

这是一个相当无用的结构,没有任何用途,除非它与模板一起使用。也就是说,如果您定义了返回值可能为“void”的模板函数。

于 2010-08-08T15:26:48.653 回答
7

您将在通用代码中使用它,其中 Foo() 的返回值未知或可能更改。考虑:

template<typename Foo, typename T> T Bar(Foo f) {
    return f();
}

在这种情况下,Bar 对 void 有效,但在返回类型更改时也有效。但是,如果它只是调用 f,那么如果 T 是非空的,那么这段代码就会中断。使用返回 f(); 如果存在 Foo() 的返回值,则语法保证保留该返回值,AND 允许 void()。

此外,明确返回是一个好习惯。

于 2010-08-08T15:31:11.340 回答
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)则模板中的 the 在被要求 wrap 时将不起作用func2

于 2010-08-08T15:32:30.627 回答
0

原因是像 math.h 一样返回内存总是返回。math.h 没有 void 也没有空参数。有许多实际情况需要记忆。

于 2010-08-08T16:23:07.690 回答
0

可能是Foo()最初返回一个值,但后来改为void,更新它的人只是没有想清楚。

于 2010-08-08T17:23:05.173 回答
0

我能想到的唯一原因是,如果您return Foo();在 switch 中有很长的语句列表并希望使其更紧凑。

于 2010-08-08T15:21:49.647 回答