Вернуть выражения в C++
Рассмотрим следующий код:
float validateEntry()
{
string entry;
float value;
getline(cin, entry);
value = atof(entry.data());
return ((isNumber(entry) && value >= 0) ? i
: (cout << "Enter valid amount: ", validateEntry())
}
Почему допускается последняя строка (выражение, разделенное запятыми), и есть ли другие выражения, которые можно использовать с операторами возврата в C++?
Меня больше всего смущает использование запятой, и я задаюсь вопросом, где определяется этот синтаксис выражения (я понятия не имел, что он существует, и я не знал, где его найти). Могу ли я заполнить это последнее выражение неопределенным количеством кода; если да, каковы ограничения, требования и т. д.?
4 ответа
Оператор запятой позволяет вам сгруппировать два не связанных между собой выражения. Оба выражения всегда вычисляются, и результат является результатом второго выражения. Почти всегда плохая идея использовать его (потому что это ухудшает читабельность, только чтобы сохранить строку кода), за исключением, может быть, в верхней части цикла for.
return [expression];
expression :
expression , expression
literal
etc...
Оператор запятой разделяет несколько выражений в одной строке. При использовании в операторе присваивания, таком как оператор возврата (присваивание временного значения, которое возвращается), присваивается только самое правое значение. Предыдущие выражения выполняются слева направо. В вашем примере возвращаемое значение окончательного вызова функции возвращается.
Я использую эту технику, чтобы очистить формальные переменные аргумента при неудаче. Особенно подпрограммы COM, где есть сбой. Например:
HRESULT func(..., IInterface **ppv)
{
...
If(!good)
return (*ppv = 0), E_FAIL;
...
}
? :
является единственным троичным оператором C++
его синтаксис logical-or-expression ? expression : conditional-expression
Вы можете прочитать больше об этом на MSDN
,
оператор так же, как +
или же <<
так что вы можете свободно использовать его почти везде, где ожидается выражение. Исключением являются контексты, в которых ожидается запятая с другим значением, например, при вызове функции. В таких случаях вы должны избавиться от запятой, добавив дополнительный набор символов:
foo((b,c)); // call foo with a single argument
Выражение, которое вы показываете, является эквивалентом:
// return ((isNumber(entry) && value >= 0) ? i : (cout << "Enter valid amount: ", validateEntry())
if(isNumber(entry) && value >= 0) {
return i;
} else {
cout << "Enter valid amount: ";
return validateEntry();
}
Это просто "умный" способ условно выполнить cout << "Enter valid amount: "
перед звонком validateEntry()
используя как можно меньше строк. Конечно, вся функция - это просто "умный" способ многократно запрашивать ввод, пока он не получит действительный ввод. ИМО цикл был бы лучше, чем рекурсия здесь.