Вернуть выражения в 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() используя как можно меньше строк. Конечно, вся функция - это просто "умный" способ многократно запрашивать ввод, пока он не получит действительный ввод. ИМО цикл был бы лучше, чем рекурсия здесь.

Другие вопросы по тегам