Учитывая функцию, которая возвращает значение, действительно ли возможно выйти из функции, учитывая определенное условие, ничего не возвращая? Если так, как можно выполнить это?
Пример:
int getNumber ()
{
. . .
}
Поэтому скажите, что Вы находитесь в этой функции. Существует ли способ выйти из него без него делающий что-нибудь?
У вас есть два варианта: вернуть
что-то или выбросить
.
int getNumber()
{
return 3;
}
int getNumber()
{
throw string("Some Var");
}
Если вы бросаете
, вы должны поймать
того типа, который вы бросили.
int maint(int argc, char ** argc)
{
try
{
getNumber();
}
catch(string std)
{
//Your code will execute here if you throw
}
}
Вы можете уйти с возвращением;
без возвращаемого значения. Компилятор выдаст предупреждение, но не ошибка.
НО , с какой стати вы вообще об этом думаете? Чего вы пытаетесь достичь?
И как выглядит вызывающий код? Если это int someVar = getNumber ();
, тогда значение someVar не определено (что является плохой вещью).
Мне кажется, вы хотите вернуть две части информации, одна из которых сообщает вам, действительна ли другая.
Попробуйте что-нибудь вроде
bool GetNumber(int * outputNumber)
{
if ....
{
*outputNumber = ...;
return true;
}
else
{
return false; // contents of outputNumber are undefined
}
}
int number;
bool isNumberValid;
isNumberValid = GetNumber(&number);
if (isNumberValid)
... do something with number
возможность просмотра заголовков ограничена в нескольких браузерах, поэтому флэш-память имеет проблемы с передачей информации. это в основном обвиняется в настройках браузера, но мне еще предстоит найти то, где он на самом деле работает. вывод события состояния .
я сдался и заставил файл напечатать код ответа в моих проектах, не замечательно (и несколько победив точку), но, кажется, работает.
-121--5085993-В окнах функции non-_r безопасны для потоков, поскольку они используют локальное место хранения потоков для буфера. См., например, http://msdn.microsoft.com/en-us/library/bf12f0hc (VS.80) .aspx
-121--2938579-Для плавающих и двойных типов существует альтернатива, но не для типов int.
#include <limits>
double Get()
{
// no valid return value
return std::numeric_limits<double>::quiet_NaN();
}
double val = Get();
if(val != val) {
// Retrieved no valid return value
}
else {
// No NaN retrieved
}
Будьте осторожны при использовании NaN. Каждое условие на валу будет верным.
Вы также можете вернуть класс / структуру с некоторым магическим преобразованием, которое будет полезно для ваших особых нужд.
Пример из реальной жизни: однажды мне действительно пришлось вернуть две части информации в одном и том же возвращаемом значении, значение, чтобы сообщить, было ли сообщение окна полностью обработано, и значение, которое будет возвращено для него, если обработка уже завершена. . Поэтому я собрал все в такой класс:
//This class is used to carry a return value for a window message and a value that indicates if the
//message has already been completely processed
class MessageReturnValue
{
public:
LRESULT returnValue;
bool processed;
MessageReturnValue()
{
processed=false;
returnValue=FALSE;
};
MessageReturnValue(LRESULT ReturnValue)
{
processed=true;
returnValue=ReturnValue;
};
MessageReturnValue(bool Processed)
{
returnValue=FALSE;
processed=Processed;
};
inline operator bool()
{
return processed;
};
inline operator LRESULT()
{
return returnValue;
};
};
Это позволило мне сделать только return false;
в функции, которая возвращала MessageReturnValue, если сообщение еще не было обработано, или return TRUE / 15 / something;
, если сообщение было полностью обработано и у меня уже было возвращаемое значение. Вызывающий, со своей стороны, мог бы просто сделать
LRESULT MyWndProc(/* blah blah blah */)
{
MessageReturnValue ret = MyFunction(/* blah blah blah */);
if(!ret)
{
/* process the message */
return /* something */;
}
else
return (LRESULT)ret;
}
. Если у вас более сложные потребности, вы также можете рассмотреть возможность использования boost :: tuple.
Простое решение:
boost::optional<int> getNumber( )
{
// May now return an int, or may return nothing.
}
Сделайте требованием для пользователя сначала проверить, что очередь не пуста (обеспечьте средства для этого).
Затем вы можете:
Проверить, а затем вызвать неопределенное поведение (возврат произвольного значения) - это худшее, что можно сделать. Вы получаете и накладные расходы времени выполнения проверки, и вызывающему ничего не остается, так как результат все равно не определен.
Альтернативой исключений является возврат кода состояния:
SomeStatusCode YourFunc(int &returnValue)
{
...
returnValue = SomeValue;
return SomeStatusCode.Successful;
...
return SomeStatusCode.Fail;
}
//in main func
if(YourFunc(retValue)==SomeStatusCode.Successful)
// work with retValue
else
// nothing to do, show error, etc.
</code>
Вы можете создать указанное исключение и соответствующим образом его перехватить.
Вы можете создать исключение . Вы ничего не вернете, но вам придется перехватить исключение, чтобы определить, что делать дальше (вы всегда можете проглотить исключение и ничего не делать для достижения желаемого).
Вы можете использовать setjmp / longjmp (см. http://en.wikipedia.org/wiki/Setjmp.h ), но с точки зрения разработки программного обеспечения лучше использовать исключения или коды ошибок, как упоминалось здесь другими.
Редизайн вашего метода, вероятно, будет правильным, если вам нужно выйти из функции, которая должна возвращать значение ... или вы можете просто вернуть значение "ошибки" какой-то.
В C ++ функция должна возвращать значение (тип значения, ссылка или адрес), если оно указано в объявлении / определении функции.
Каков ваш реальный сценарий использования?
Если вам действительно нужно ничего не возвращать и прервать нормальное выполнение функции, вы можете бросить исключение.
Вы также можете вернуть что-то, что вызывающая сторона интерпретирует как ошибку (или "ничего не возвращено").
Каким бы ни было ваше решение, вызывающая сторона должна отдельно обработать случай "ничего не возвращается", например, поймать исключение или проверить возвращаемое значение.