在C++中从一个void函数返回

12

考虑以下代码片段:

void Foo()
{
  // ...
}

void Bar()
{
  return Foo();
}

在C++中,与更常见的方法相比,使用上述方法的合理原因是什么:

void Foo()
{
  // ...
}

void Bar()
{
  Foo();

  // no more expressions -- i.e., implicit return here
}
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在一个变量中并在返回之前对其进行操作,那么你仍然会遇到麻烦——你必须为void专门化(或重载)do_something_and_return

谢谢。所有答案都很好,但这个很好地阐述了重点。 - kirk0

9

这是一个毫无用处的结构,除非它与模板一起使用。也就是说,如果您已经定义了返回值可能为 "void" 的模板函数。


5
那么它几乎不是“无用”的,是吗? ;) - jalf
@jalf:嗯,在问题中展示的形式中,它是相当无用的,不是吗?;-) - Stefan Rådström
足够正确。我将问题中的代码解释为语言特性的示例,并询问语言特性“总体上”何时有用。但是,你说得对。 ;) - jalf

7

当你的代码是通用的,而且Foo()函数的返回值未知或可能会改变时,你可以使用它。例如:

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

在这种情况下,Bar对于void是有效的,但如果返回类型发生变化,它也是有效的。然而,如果它只被称为f,那么如果T不是void,这段代码将会出错。使用return f();语法可以保证Foo()的返回值(如果存在)得以保存,并允许void()。此外,显式返回是一个很好的习惯。

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时将无法工作。

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

0

原因是像 math.h 一样的返回内存。math.h 没有空类型和空参数。在许多实际情况中,你需要内存。


什么?数学函数需要接受参数并返回值,因为这是它们作为数学函数所必须做的事情... - GManNickG

0

可能存在这样一种情况,即Foo()最初返回一个值,但后来被更改为void,并且更新它的人没有思考得很清楚。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接