Предположим, что класс существует следующим образом:
class Foo
{
void do_after_something()
{
//some code here
return;
}
void do_something()
{
//some code here
return do_after_something(); //returning another (void) function
}
};
JAVA явно выступает против чего-то подобного, компилятор Borland C ++ выдает предупреждение,
MS VC ++ не жалуется.
return do_after_something();
в отличие от:
do_after_something();
return;
или же это все зависит от реализации (компилятор / язык)?
Философски, ты мог утверждают, что возвращая результат void
Функция возврата должна быть разрешена, но, к сожалению, это не так, по крайней мере, для Java.
Это является допустимо для C ++, однако. Если вы попробуете следующую программу:
#include <iostream>
void xyzzy(void) {}
void plugh(void) { return xyzzy();}
int main() {
std::cout << "Hello\n";
plugh();
return 0;
}
это будет работать нормально.
Это подробно описано в ISO C++11 6.6.3 /3
:
Оператор возврата с выражением типа
void
может использоваться только в функциях с типом возвратаcv void
; выражение вычисляется непосредственно перед тем, как функция возвращается к своему вызывающему.
Таким образом, действительно одинаково справедливо утверждать, что путь Java является правильным, если вы думаете о void
как не фактический тип, а как отсутствие чего-либо. Например, когда у вас есть:
int xyzzy(void) { return 42; }
в C вы не обязаны предоставлять аргумент правильного (не) типа, например:
void plugh;
int twisty = xyzzy(plugh);
То же самое относится и к C ++, но по-другому — языки такие, какие есть.
Я думаю, что это должно быть разрешено и считается действительным на всех языках. Если у вас есть функция, тип возвращаемого значения void
и вы возвращаете результат выражения, тип которого void
(например, позвонив другому void
функция), вы удовлетворили это ограничение.
Это не считается полезным в C (хотя я думаю, что это может быть разрешено), потому что нет причин для этого. В любое время вы делаете:
return someVoidFn();
Вы всегда можете перевести это на:
someVoidFn();
return;
И получить точно такой же эффект.
Однако в C ++ и Java, возвращая void
функция имеет реальное применение, и это потому, что эти языки шаблоны и дженерики. Рассмотрим этот (не очень полезный) класс Java:
class NestedIdentity<T> {
T run(int i, T value) {
if (i == 0) return value;
return run(i - 1);
}
}
это run
Метод возвращает значение, которое вы передаете ему, после вызова себя определенное количество раз. Я знаю, бессмысленно, верно? Но важная часть заключается в том, что T
может быть недействительным. Вы можете сделать это:
NestedIdentity<Void> nest = new NestedIdentity<Void>();
nest(5, null);
А также это работает. В Java Void
(обратите внимание на заглавную букву) создает универсальный с void
-подобный тип, единственное значение которого null
, Если Java не позволяет вернуть void
выражение в void
метод, это должно быть ошибка времени компиляции для создания экземпляра универсального с помощью void.
В C ++ 11 это возможно и законно. Вы можете вернуть функцию void из другой функции void.
Refrence Язык программирования C ++ Глава 12, Бьярне Струструп