【问题标题】:Returning From a Void Function in C++从 C++ 中的 void 函数返回
【发布时间】:2011-03-26 23:25:03
【问题描述】:

考虑以下 sn-p:

void Foo()
{
  // ...
}

void Bar()
{
  return Foo();
}

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

void Foo()
{
  // ...
}

void Bar()
{
  Foo();

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

【问题讨论】:

    标签: c++ return void


    【解决方案1】:

    在您的示例中可能没有用,但在某些情况下很难在模板代码中处理 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 存储在一个变量中并在返回之前对其进行处理,那么你仍然会遇到麻烦 - 你' d 必须专门化(或重载)do_something_and_return 为 void。

    【讨论】:

    • 谢谢。所有的答案都很好,但这一个很好地说明了这一点。
    【解决方案2】:

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

    【讨论】:

    • 那么它几乎没有“无用”,是吗? ;)
    • @jalf:好吧,以问题中显示的形式,它非常没用,不是吗? ;-)
    • 确实如此。我将问题中的代码解释为语言功能的示例,并询问语言功能一般何时有用。但公平点。 ;)
    【解决方案3】:

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

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

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

      【讨论】:

        【解决方案5】:

        我能想到的唯一原因是,如果你在 switch 中有一个很长的 return Foo(); 语句列表,并且想让它更紧凑。

        【讨论】:

          【解决方案6】:

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

          【讨论】:

          • 什么?数学函数接受参数并返回值,因为这是它们成为数学函数所需要做的......
          【解决方案7】:

          可能是Foo()原来是返回了一个值,后来改成了void,只是更新的人没想清楚。

          【讨论】:

            猜你喜欢
            • 2016-08-28
            • 2021-04-02
            • 1970-01-01
            • 2015-01-24
            • 1970-01-01
            • 2017-07-13
            • 2012-02-26
            • 2015-01-12
            • 2010-11-16
            相关资源
            最近更新 更多