Пользователь перегружен логическими операторами в C ++ ( &&, ||
) ведут себя как обычные функции. То есть оба аргумента в bool operator&&(const T &a, const T2 &b);
оцениваются перед вводом функции, так как ввод функции является точкой последовательности [1] в C ++. Все хорошо до здесь.
Теперь «встроенные операторы && и || выполнить оценку короткого замыкания »[2] [3], где между левой и правой сторонами есть точка последовательности. В цитируемой ссылке неясно, что такое «встроенный», только то, что они принимают bool
операнды или конвертировать их, используя «контекстное преобразование в bool». В нем также упоминается, что «только два стандартных библиотечных класса перегружают эти операторы [потому что] свойства короткого замыкания (…) не применяются к перегрузкам, а также потому, что типы с логической семантикой встречаются редко» [2].
Типы с булевой семантикой? Как именно работают «встроенные операторы»? Просто невозможно определить логические операторы с оценкой короткого замыкания?
[1] https://en.wikipedia.org/wiki/Sequence_point [2] http://en.cppreference.com/w/cpp/language/operator_logical [3] https://en.wikipedia.org/wiki/Short-circuit_evaluationВы можете себе представить, что короткое замыкание &&
действует так:
bool b = expr1 && expr2;
во-первых, требуется expr1
а также expr2
и хранит их в лямбдах:
bool b = and_helper( [&]{return expr1;}, [&]{return expr2;} );
и направляет их к помощнику, где and_helper
есть (слегка упрощено):
template<class Lhs, class Rhs>
bool and_helper( Lhs&& lhs, Rhs&& rhs ) {
if (lhs()) return rhs();
return false;
}
это имеет подобное поведение короткого замыкания.
Для переопределенных пользователей &&
чтобы работать таким образом, мы должны были бы автоматически лямбда аргументов и передать лямбда в написанное пользователем operator&&
,
Таким образом, единственным препятствием для этого при выполнении пользовательских операций является синтаксический. Вы можете получить такое же поведение после относительно механического преобразования ваших типов, не прибегая к магии.
Компилятор только что сделал примерно эквивалентную операцию (даже до того, как лямбды существовали), когда столкнулся с этой конструкцией.
Это означает, что короткое замыкание не относится к пользовательским операторам.
Это потому, что, как вы сказали, они ведут себя как функции.