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対処する必要があることに注意してください。中間関数は汎用です。voidretvaldo_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がvoidでない場合、このコードは壊れます。リターンf();を使用します。構文は、Foo()の戻り値が存在する場合はその値の保持を保証し、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)、ラップするように要求されたときにテンプレート内のが機能しませんでしたfunc2

于 2010-08-08T15:32:30.627 に答える
0

私が考えることができる唯一の理由はreturn Foo();、スイッチにステートメントの長いリストがあり、それをよりコンパクトにしたい場合です。

于 2010-08-08T15:21:49.647 に答える
0

その理由は、math.hが常に返すようにメモリを返すためです。math.hにはvoid引数も空の引数もありません。あなたが記憶を必要とする多くの実際的な状況があります。

于 2010-08-08T16:23:07.690 に答える
0

Foo()最初に値を返したが、後でに変更されvoid、それを更新した人があまり明確に考えていなかった場合である可能性があります。

于 2010-08-08T17:23:05.173 に答える