2016-03-10 2 views
0

Пользовательские перегруженные логические операторы в C++ (&&, ||) ведут себя как обычные функции. То есть оба аргумента в bool operator&&(const T &a, const T2 &b); оцениваются перед входом в функцию, так как ввод функции является точкой последовательности [1] в C++. Все хорошо здесь.Оценка короткого замыкания на 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

+4

«Разве просто невозможно определить логические операторы с оценкой короткого замыкания?» Да, это просто невозможно. Ваша операторская функция нуждается в обоих аргументах, полностью оценивается, что означает, что компилятор просто не может делать короткое замыкание. Если вам нужна оценка короткого замыкания вашего собственного типа, тогда вам нужно реализовать операторы преобразования вместо 'bool' вместо логического оператора. –

+1

Мое чтение гласит, что «встроенный» означает «это встроенная функция языка», а не «это часть стандартной библиотеки». Вы не можете создавать собственные встроенные операторы, если только вы не создаете собственный компилятор с собственными нестандартными расширениями. –

+0

Возможный дубликат [Есть ли на самом деле причина перегрузки && и || не замыкайте?] (http://stackoverflow.com/questions/25913237/is-there-actually-a-reason-why-overloaded-and-dont-short-circuit) – quamrana

ответ

0

Это означает, что короткое замыкание не распространяется на определенных пользователем операторов.

Это потому, что, как вы сказали, они ведут себя как функции.

2

Вы можете себе представить, что при коротком замыкании && действует как это:

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; 
} 

имеет аналогичное поведение при коротком замыкании.

Для удобства пользователя &&, чтобы работать таким образом, нам нужно авто-лямбда аргументы и передать указанные lambdas в пользовательский operator&&.

Таким образом, единственный барьер, который может произойти с пользовательскими операциями, является синтаксическим. Вы можете получить такое же поведение после относительно механической трансформации своих типов, не прибегая к магии.

Компилятор выполнил примерно эквивалентную операцию (даже до того, как существовал лямбда), когда он столкнулся с этой конструкцией.

Смежные вопросы