Pytanie Czy wyrażenia warunkowe w C ++ są zawsze typu bool?


W C zorientowane warunkowo operatory oceniają albo 1 lub 0 typu int (nawet jeśli ma dedykowane _Bool rodzaj). Odnosi się do Przeciągnięcie C11 N1570:

C11 §6.5.8 / 6 Operatorzy relacyjni

Każdy z operatorów < (mniej niż), > (Lepszy niż), <= (mniej niż   lub równe), oraz >= (większy lub równy) daje 1, jeżeli   określona relacja ma wartość true, a 0, jeśli jest false.107) Rezultat został osiągnięty   rodzaj int.

C11 §6.5.9 / 3 Operatorzy ds. Równości

The == (równe) i != (nie równe) operatory są analogiczne do   operatory relacyjne, z wyjątkiem ich niższego pierwszeństwa.108) Każdy z   operatory dają 1, jeśli podana relacja jest prawdziwa, a 0, jeśli jest   to fałsz. Wynik ma typ int. Dla każdej pary operandów, dokładnie   jedna z relacji jest prawdziwa.

C11 6.5.13 / 3 Logiczny operator AND

The && operator daje 1, jeśli oba operandy są nierówne   do 0; w przeciwnym razie daje 0. Wynik ma typ int.

C11 6.5.14 / 3 Logiczny operator OR

The || operator powinien ustąpić 1, jeśli jeden z jego argumentów porówna   nierównomierny do 0; w przeciwnym razie daje 0. Wynik ma typ int.

Jak sprawdziłem C ++ wydaje się być inny w tej kwestii, jak w poniższym przykładzie (zob http://ideone.com/u3NxfW):

#include <iostream>
#include <typeinfo>

int main() {
    double x = 10.0;

    std::cout << typeid(x <= 10.0).name() << std::endl;

    return 0;
}

wyniki b, co, jak sądzę, wskazuje bool rodzaj. Czy C ++ gwarantuje, że wszyscy operatorzy zawsze oceniają bool type (w przeciwieństwie do C)?


14
2018-01-22 14:45


pochodzenie




Odpowiedzi:


W przeciwieństwie do C, w C ++, operatory relacyjne, operatory równości i operatory logiczne (logiczne AND, logiczne OR i logiczne negacje) dają wszystkie wartości typu bool.

Na przykład:

(C ++ 11, 5.9p1 Operatory relacyjne) "[...] Typ wyniku to bool."

EDYTOWAĆ: ze względu na kompletność wszystkie wymienione powyżej operatory mogą być przeciążone, a zatem wynikowy typ może zostać zmieniony. Zobacz odpowiedź Arne Vogel na prawdziwe życie przykład.


11
2018-01-22 14:53



Zakładając, że nie zostały przesłonięte. - Raymond Chen
Ach, "róg nitpicker'a" powrócił :) - Bulletmagnet
@Bulletmagnet To coś więcej niż gnój, ponieważ strasznie dużo porównań w C ++ będzie dotyczyć operatorów zdefiniowanych przez użytkownika, którzy mogą (ale nie powinni) zwracać żadnego typu. - James Kanze


Nie, z powodu przeciążenia operatora. Zostało to wspomniane wcześniej, ale mogę podać przykład z życia szablony wyrażeń. Ogólnie rzecz biorąc, idea ta pozwala na pisanie "leniwych" wyrażeń (to jest, naprawdę, obiektów funkcyjnych lub ASTs) ze składnią, która jest bardzo podobna do normalnego, chętnego użycia operatorów logicznych. Zwykle przeciążane jest również wiele innych operatorów, w szczególności operatorów arytmetycznych.

Na przykład jednym z celów projektu Boost.Lambda było uproszczenie stosowania algorytmów:

std::string str;
// ...
std:.string::iterator firstA = std::find_if(str.begin(), str.end(), _1 == 'a' || _1 == 'A');

Poprzednio w "czystym" C ++ 98 konieczne było zazwyczaj pisanie wielu nazwanych funkcji lub obiektów funkcyjnych, zanim wiele standardowych algorytmów mogłoby być efektywnie wykorzystanych.

Od czasu C ++ 11, Boost.Lambda nie jest już tak przydatna, ponieważ wyrażenia lambda zostały dodane do języka podstawowego. Wciąż istnieje wiele EDSL (wbudowanych języków specyficznych dla danej domeny), gdzie lambdy C ++ 11 nie mogą zastąpić szablonów ekspresji, np. możesz chcieć generować ciągi poleceń SQL bezpośrednio z C ++ EDSL w sposób podobny do LINQ w .NET, ale jako przenośne rozwiązanie biblioteki. Inny przykład: VexCL biblioteka używa szablonów ekspresji do generowania jądra GPU.

Jest to prawdopodobnie jedyne uprawnione użycie zwrotów nieobjętych boolem dla przeciążonych operatorów logicznych, ale generalnie nie jest to uważane za ezoteryczne.


12
2018-01-22 16:43