Возврат из пустой функции в C++

Рассмотрите следующий отрывок:

void Foo()
{
  // ...
}

void Bar()
{
  return Foo();
}

Что является законной причиной использовать вышеупомянутое в C++ в противоположность более общему подходу:

void Foo()
{
  // ...
}

void Bar()
{
  Foo();

  // no more expressions -- i.e., implicit return here
}
11
задан kirk0 8 August 2010 в 15:15
поделиться

7 ответов

Вероятно, бесполезно в вашем примере, но есть некоторые ситуации, когда трудно справиться с 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 для недействительности.

16
ответ дан 3 December 2019 в 01:51
поделиться

Вы могли бы использовать его в универсальном коде, где возвращаемое значение Foo () неизвестно или может быть изменено. Учтите:

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

В этом случае Bar действителен для void, но также действителен при изменении типа возвращаемого значения. Однако, если бы он просто вызвал f, этот код сломался бы, если бы T не был недействительным. Используя return f (); синтаксис гарантирует сохранение возвращаемого значения Foo (), если оно существует, И допускает void ().

Кроме того, явное возвращение - хорошая привычка.

7
ответ дан 3 December 2019 в 01:51
поделиться

Может быть случай, когда Foo () первоначально возвращал значение, но позже было изменено на void , и человек, который обновил его, просто не сделал этого. непонятно.

0
ответ дан 3 December 2019 в 01:51
поделиться

Это довольно бесполезная конструкция, которая бесполезна, если не используется с шаблонами. То есть, если вы определили функции шаблона, которые возвращают значение, которое может быть «недействительным».

9
ответ дан 3 December 2019 в 01:51
поделиться

Шаблоны:

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 .

4
ответ дан 3 December 2019 в 01:51
поделиться

Единственная причина, которую я могу придумать, - это если у вас есть длинный список операторов return Foo (); в переключателе, и вы хотите сделать его более компактным.

0
ответ дан 3 December 2019 в 01:51
поделиться

Причина в возврате памяти, как в математике. .h всегда возвращается. math.h не имеет пустых и пустых аргументов. Есть много практических ситуаций, когда вам нужна память.

0
ответ дан 3 December 2019 в 01:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: