Следующее сомнительно минимальный, полный, проверяемый пример. Это не вопрос о том, как улучшить этот код. Что я хочу знать, так это то, что стандарт оправдывает использование операторов короткого замыкания вне условного, как показано в main
,
enum weekday {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
WEEKDAY_SIZE
};
bool getWeekday(int index, weekday& result) {
result = static_cast<weekday>(index);
return index >= 0 && index < static_cast<int>(WEEKDAY_SIZE);
}
bool getName(weekday& index, string& result) {
switch (static_cast<weekday>(index)) {
case SUNDAY:
result = "Sunday";
break;
case MONDAY:
result = "Monday";
break;
case TUESDAY:
result = "Tuesday";
break;
case WEDNESDAY:
result = "Wednesday";
break;
case THURSDAY:
result = "Thursday";
break;
case FRIDAY:
result = "Friday";
break;
case SATURDAY:
result = "Saturday";
break;
default:
assert("Short Circut Failed");
return false;
}
return true;
}
int main() {
const int index = 0;
weekday Weekday;
string Name;
getWeekday(index, Weekday) && getName(Weekday, Name);
cout << Name << endl;
}
Это работает как для Visual Studio 2015 и gcc 5.1 без утверждения.
Из стандарта C ++ 14, раздел 5.14:
1 && оператор группы слева направо. Оба операнда
контекстно преобразуется в bool (пункт 4). Результат верен, если
оба операнда являются истинными и ложными в противном случае. В отличие от & , && гарантии
оценка слева направо: второй операнд не оценивается, если
первый операнд неверен.2 Результатом является bool. Если второе
Выражение оценивается, каждое значение вычисления и побочный эффект
связанный с первым выражением упорядочен перед каждым значением
вычисления и побочный эффект, связанный со вторым выражением.
Стандарт ничего не говорит о контексте того, где &&
используется. Если левая сторона оценивается как ложная, правая сторона не оценивается.
В этом контексте результат выражения отбрасывается, как если бы вы сделали это:
1;
Это не работа стандарта потворствовать стилям кодирования.
Там нет ничего плохого в вашем письме getWeekday(index, Weekday) && getName(Weekday, Name);
Читатель вашего кода будет знать, что getName(Weekday, Name)
не будет вызван, если getWeekday(index, Weekday)
оценивает false
,