Zagadnienia ogólne | ||||
Kontrola przepływu | ||||
Warunkowe instrukcje wykonania | ||||
|
||||
Instrukcje iteracyjne (pętle) | ||||
zakres-. |
||||
Funkcje | ||||
Deklaracja funkcji | ||||
Deklaracja funkcji lambda | ||||
inline specyfikator |
||||
Specyfikatory wyjątków (do C++20) | ||||
. noexcept specifier (C++11) |
||||
Exceptions | ||||
Namespaces | ||||
Typy | ||||
Specyfikatory | ||||
|
. |
|||
Specyfikatory czasu przechowywania | ||||
. Inicjalizacja | ||||
Wyrażenia | ||||
Reprezentacje alternatywne | ||||
Literały | ||||
Boolean – ang. Integer – Floating-point | ||||
Character – String – nullptr (C++11) |
||||
User-zdefiniowane (C++11) | ||||
Utilities | ||||
Atrybuty (C++11) | ||||
Typy | ||||
. typedef deklaracja |
||||
Deklaracja aliasu typu (C++11) | ||||
Rzutowanie | ||||
Konwersje niejawne -. Konwersje jawne | ||||
static_cast – dynamic_cast |
||||
const_cast -. reinterpret_cast |
||||
Alokacja pamięci | ||||
Klasy | ||||
Klasy-.specyficzne właściwości funkcji | ||||
Funkcja wirtualna specyfikator override (C++11) specyfikator final (C++11) |
. |
|||
Specjalne funkcje członkowskie | ||||
Przypisanie kopiowania Przypisanie przenoszenia (C++11) Destruktor |
||||
Szablony | ||||
Specjalizacja szablonów Pakiety parametrów (C++11) |
||||
Różne | ||||
Ogólne
kategorie wartości (lvalue, rvalue, xvalue)
kolejność oceny (punkty sekwencji)
wyrażenia stałe
wyrażenia niedokonujące oceny
wyrażenia pierwotne
wyrażenia lambda(C++11)
wyrażenia literalne
wyrażenia całkowite
wyrażenia zmiennoprzecinkowepunktowe
literały boolean
literały znaków, w tym sekwencje ucieczki
literały łańcuchów
literał wskaźnika null(C++11)
literał zdefiniowany przez użytkownika(C++11)
Operatory
Operatory przypisania: a=b
, a+=b
, a-=b
, a*=b
, a/=b
, a%=b
, a&=b
, a|=b
, a^=b
, a<<=b
, a>>=b
Inkrementacja i dekrementacja: ++a
, --a
, a++
, a--
Operatory arytmetyczne:+a
, -a
, a+b
, a-b
, a*b
, a/b
, a%b
, ~a
, a&b
, a|b
, a^b
, a<<b
, a>>b
Operatory logiczne: a||b
, a&&b
, !a
Operatory porównania: a==b
, a!=b
, a<b
, a>b
, a<=b
, a>=b
, a<=>b
(C++20)
Operatory dostępu do członów: a
, *a
, &a
, a->b
, a.b
, a->*b
, a.*b
Inne operatory: a(...)
, a,b
, a?b:c
new-expression
delete-expression
throw-expression
alignof
sizeof
sizeof….(C++11)
typeid
noexcept(C++11)
Wyrażenie składane(C++17)
Alternatywne reprezentacje operatorów
Precedencja i asocjatywność
Przeciążanie operatorów
. Domyślne porównania(C++20)
Konwersje
Konwersje niejawne
const_cast
static_cast
reinterpret_cast
dynamic_cast
Konwersje jawne (T)a
, T(a)
konwersja zdefiniowana przez użytkownika
Zwraca wynik określonej operacji arytmetycznej.
Nazwa operatora | Składnia | Przeciążalny | Przykłady prototypów (dla klasy T) | |
---|---|---|---|---|
Wewnątrz definicji klasy | Na zewnątrz definicji klasy | |||
unary plus | +a |
Tak | T T::operator+() const; | T operator+(const T &a); |
unary minus | -a |
Yes | T T.::operator-() const; | T operator-(const T &a); |
dodawanie | a + b |
Tak | T T::operator+(const T2 &b) const; | T operator+(const T &a, const T2 &b); |
odejmowanie | a - b |
Tak | T T::operator-(const T2 &b) const; | T operator-(const T &a, const T2 &b); |
mnożenie | a * b |
Tak | T T.::operator*(const T2 &b) const; | T operator*(const T &a, const T2 &b); |
dzielenie | a / b |
Tak | T T.::operator/(const T2 &b) const; | T operator/(const T &a, const T2 &b); |
modulo | a % b |
Tak | T T::operator%(const T2 &b) const; | T operator%(const T &a, const T2 &b); |
bitwise NOT | ~a |
Yes | T T.::operator~() const; | T operator~(const T &a); |
bitwise AND | a & b |
Yes | T T::operator&(const T2 &b) const; | T operator&(const T &a, const T2 &b); |
bitwise OR | a | b |
Tak | T T.::operator|(const T2 &b) const; | T operator|(const T &a, const T2 &b); |
bitwise XOR | a ^ b |
Yes | T T::operator^(const T2 &b) const; | T operator^(const T &a, const T2 &b); |
bitowe przesunięcie w lewo | a << b |
Tak | T T::operator<<(const T2 &b) const; | T operator<<(const T &a, const T2 &b); |
bitwise right shift | a >> b |
Yes | T T.:::operator>>(const T2 &b) const; | T operator>>(const T &a, const T2 &b); |
Uwagi
|
Zawartość
- 1 Objaśnienie
- 1.1 Konwersje
- 1.2 Przepełnienia
- 1.3 Środowisko zmiennoprzecinkowe
- 1.4 Skurcz zmiennoprzecinkowy
- 1.5 Operatory arytmetyki jednoargumentowej
- 1.6 Operatory addytywne
- 1.7 Operatory multiplikatywne
- 1.8 Bitowe operatory logiczne
- 1.9 Operatory przesunięć bitowych
- 2 Biblioteka standardowa
- 2.1 Operatory arytmetyki unarnej
- 2.2 Operatory addytywne
- 2.3 Operatory multiplikatywne
- 2.4 Operatory logiczne bitowe
- 2.5 Operatory przesunięć bitowych
- 2.6 Operatory wstawiania/wyciągania strumienia
- 3 Raporty o wadach
- 4 Zobacz także
Objaśnienie
Wszystkie operatory arytmetyczne obliczają wynik określonej operacji arytmetycznej i zwracają jej wynik. Argumenty nie są modyfikowane.
Konwersje
Jeśli operand przekazany operatorowi arytmetycznemu jest typu integralnego lub nieskorelowanego typu wyliczeniowego, to przed jakimkolwiek innym działaniem (ale po konwersji z wartości na wartość, jeśli ma to zastosowanie) operand przechodzi promocję integralną. Jeśli operand ma typ tablicowy lub funkcyjny, stosowane są konwersje typu tablica na wskaźnik i funkcja na wskaźnik.
Dla operatorów binarnych (z wyjątkiem przesunięć), jeśli promowane operandy mają różne typy, stosowany jest dodatkowy zestaw niejawnych konwersji, znany jako zwykłe konwersje arytmetyczne, których celem jest wyprodukowanie wspólnego typu (dostępnego również przez cechę typu std::common_type). Jeśli, przed jakąkolwiek promocją integralną, jeden z operandów jest typu wyliczeniowego, a drugi operand jest typu zmiennoprzecinkowego lub innego typu wyliczeniowego, to zachowanie to jest zdeprecjonowane. (od C++20)
- Jeśli jeden z operandów ma typ wyliczeniowy, to konwersja nie jest wykonywana: drugi operand i typ zwracany muszą mieć ten sam typ
- W przeciwnym razie, jeśli którykolwiek z operandów jest long double, drugi operand jest konwertowany na long double
- W przeciwnym razie, jeśli którykolwiek z operandów jest double, drugi operand jest konwertowany na double
- W przeciwnym razie, Jeśli którykolwiek z operandów jest float, drugi operand jest konwertowany na float
- W przeciwnym razie operand ma typ integer (ponieważ bool, char, char8_t, char16_t, char32_t, wchar_t i unscoped enumeration zostały promowane w tym momencie) i integralne konwersji są stosowane do produkcji wspólnego typu, jak poniżej:
- Jeśli oba operandy są podpisane lub oba są niepodpisane, operand o mniejszym stopniu konwersji jest konwertowany na operand o większym stopniu konwersji liczby całkowitej
- W przeciwnym razie, jeśli stopień konwersji niepodpisanego operandu jest większy lub równy stopniowi konwersji podpisanego operandu, podpisany operand jest konwertowany na typ niepodpisanego operandu.
- W przeciwnym razie, jeśli typ podpisanego operandu może reprezentować wszystkie wartości niepodpisanego operandu, niepodpisany operand jest konwertowany na typ podpisanego operandu
- W przeciwnym razie oba operandy są konwertowane na niepodpisany odpowiednik typu podpisanego operandu.
Ranga konwersji powyżej wzrasta w kolejności bool, signed char, short, int, long, long long. Ranga każdego niepodpisanego typu jest równa randze odpowiadającego mu podpisanego typu. Ranga char jest równa randze podpisanego char i unsigned char. Rangi char8_t, char16_t, char32_t i wchar_t są równe rangom ich podstawowych typów.
Przepełnienia
Unsigned integer arithmetic jest zawsze wykonywany modulo 2n
gdzie n jest liczbą bitów w tej konkretnej liczbie całkowitej. Np. dla unsigned int, dodanie jedynki do UINT_MAX daje 0, a odjęcie jedynki od 0 daje UINT_MAX.
Gdy podpisana operacja arytmetyczna na liczbach całkowitych przepełnia się (wynik nie mieści się w typie wynikowym), zachowanie jest niezdefiniowane, – możliwe przejawy takiej operacji obejmują:
- owija się zgodnie z regułami reprezentacji (typowo 2’s complement),
- wpada w pułapkę – na niektórych platformach lub ze względu na opcje kompilatora (np.np.
-ftrapv
w GCC i Clang), - nasyca się do wartości minimalnej lub maksymalnej (na wielu DSP),
- jest całkowicie zoptymalizowany przez kompilator.
Środowisko zmiennoprzecinkowe
Jeśli #pragma STDC FENV_ACCESS jest obsługiwana i ustawiona na ON
, wszystkie operatory arytmetyki zmiennoprzecinkowej przestrzegają bieżącego kierunku zaokrąglania zmiennoprzecinkowego i zgłaszają błędy arytmetyki zmiennoprzecinkowej, jak określono w math_errhandling, chyba że są częścią inicjalizatora statycznego (w tym przypadku wyjątki zmiennoprzecinkowe nie są zgłaszane, a trybem zaokrąglania jest nearest)
Skurcz zmiennoprzecinkowy
Jeśli #pragma STDC FP_CONTRACT jest obsługiwana i ustawiona na OFF
, cała arytmetyka zmiennoprzecinkowa może być wykonywana tak, jakby wyniki pośrednie miały nieskończony zakres i precyzję, to znaczy, dozwolone są optymalizacje, które pomijają błędy zaokrągleń i wyjątki zmiennoprzecinkowe. Na przykład, C++ pozwala na implementację (x*y) + z za pomocą pojedynczej instrukcji multiply-add CPU lub optymalizację a = x*x*x; jako tmp = x *x; a = tmp*tmp.
Niezwiązane z kontraktowaniem, pośrednie wyniki arytmetyki zmiennoprzecinkowej mogą mieć zakres i precyzję, która jest inna niż wskazana przez jej typ, zobacz FLT_EVAL_METHOD
Ogólnie, standard C++ nie gwarantuje dokładności operacji zmiennoprzecinkowych.
Operatory arytmetyczne jednoargumentowe
Wyrażenia operatorów arytmetycznych jednoargumentowych mają postać
+ wyrażenie |
. (1) | ||||||||
- wyrażenie |
(2) | ||||||||
Wbudowany operator unarny plus zwraca wartość swojego operandu. Jedyną sytuacją, gdy nie jest to no-op, jest gdy operand ma typ integralny lub typ wyliczeniowy, który jest zmieniany przez promocję integralną, np. konwertuje char na int lub gdy operand podlega konwersji lvalue-to-rvalue, array-to-pointer lub function-to-pointer.
Wbudowany jednoargumentowy operator minus oblicza minus swojego promowanego operandu. Dla unsigned a
, wartością -a
jest 2b
-a, gdzie b
jest liczbą bitów po promocji.
W rozdzielczości przeciążania przeciwko operatorom zdefiniowanym przez użytkownika, dla każdego promowanego typu arytmetycznego A
i dla każdego typu T
, następujące sygnatury funkcji uczestniczą w rozdzielczości przeciążania:
#include <iostream>int main(){ char c = 0x6a; int n1 = 1; unsigned char n2 = 1; unsigned int n3 = 1; std::cout << "char: " << c << " int: " << +c << '\n' << "-1, where 1 is signed: " << -n1 << '\n' << "-1, where 1 is unsigned char: " << -n2 << '\n' << "-1, where 1 is unsigned int: " << -n3 << '\n'; char a; std::cout << "size of array: " << sizeof a << '\n' << "size of pointer: " << sizeof +a << '\n';}
Output:
char: j int: 106-1, where 1 is signed: -1-1, where 1 is unsigned char: -1-1, where 1 is unsigned int: 4294967295size of array: 3size of pointer: 8
Operatory addytywne
Wyrażenia binarnych operatorów arytmetycznych addytywnych mają postać
lhs + rhs. |
(1) | ||||||||
lhs - rhs |
(2) | ||||||||
- oba mają typ arytmetyczny lub unscoped enumeration. W tym przypadku, zwykłe konwersje arytmetyczne są wykonywane na obu operandach i określają typ wyniku.
- jeden jest wskaźnikiem do całkowicie zdefiniowanego typu obiektu, drugi ma typ integralny lub unscoped enumeration. W tym przypadku, typ wyniku ma typ wskaźnika.
- oba mają typ arytmetyczny lub unscoped enumeration. W tym przypadku, zwykłe konwersje arytmetyczne są wykonywane na obu operandach i określają typ wyniku.
- lhs jest wskaźnikiem do całkowicie zdefiniowanego typu obiektu, rhs ma typ integralny lub unscoped enumeration. W tym przypadku, typ wyniku ma typ wskaźnika.
- oba są wskaźnikami do tych samych całkowicie zdefiniowanych typów obiektów, ignorując kwalifikatory cv. W tym przypadku typem wynikowym jest std::ptrdiff_t.
W przypadku operandów typu arytmetycznego lub wyliczeniowego, wynikiem operatora binarnego plus jest suma operandów (po zwykłych konwersjach arytmetycznych), a wynikiem operatora binarnego minus jest wynik odjęcia drugiego operandu od pierwszego (po zwykłych konwersjach arytmetycznych), z wyjątkiem tego, że jeśli typ obsługuje arytmetykę zmiennoprzecinkową IEEE (zobacz std::numeric_limits::is_iec559),
- jeśli jeden z operandów jest NaN, wynik jest NaN
- nieskończoność minus nieskończoność jest NaN i FE_INVALID jest podniesiony
- nieskończoność plus ujemna nieskończoność jest NaN i FE_INVALID jest podniesiony
Jeśli którykolwiek z operandów jest wskaźnikiem, stosuje się następujące zasady:
- Wskaźnik do obiektu niebędącego tablicą jest traktowany jako wskaźnik do pierwszego elementu tablicy o rozmiarze 1.
- Jeśli wskaźnik
P
wskazuje nai
element tablicy, to wyrażeniaP+n
,n+P
iP-n
są wskaźnikami tego samego typu, które wskazują odpowiednio nai+n
,i+n
ii-n
element tej samej tablicy. Wynikiem dodawania wskaźników może być również wskaźnik jeden za końcem (czyli wskaźnikP
taki, że wyrażenieP-1
wskazuje na ostatni element tablicy). Wszelkie inne sytuacje (to znaczy, próby wygenerowania wskaźnika, który nie wskazuje na element tej samej tablicy lub jeden za końcem) wywołują niezdefiniowane zachowanie. - Jeśli wskaźnik
P
wskazuje nai
element tablicy, a wskaźnikQ
wskazuje naj
element tej samej tablicy, to wyrażenieP-Q
ma wartość i-j, jeśli wartość mieści się w std::ptrdiff_t. Oba operandy muszą wskazywać na elementy tej samej tablicy (lub jeden za końcem), w przeciwnym razie zachowanie jest niezdefiniowane. Jeśli wynik nie mieści się w std::ptrdiff_t, zachowanie jest niezdefiniowane. - W każdym przypadku, jeśli typ wskazywany jest różny od typu elementu tablicy, pomijając kwalifikacje cv, na każdym poziomie, jeśli elementy są same wskaźnikami, zachowanie arytmetyki wskaźnikowej jest niezdefiniowane. W szczególności, arytmetyka wskaźnikowa ze wskaźnikiem do bazy, który wskazuje na element tablicy obiektów pochodnych jest niezdefiniowana.
- Jeśli wartość 0 jest dodawana lub odejmowana od wskaźnika, wynikiem jest wskaźnik, niezmieniony. Jeśli dwa wskaźniki wskazują na ten sam obiekt lub oba są o jeden za końcem tej samej tablicy, lub oba są wskaźnikami null, to wynik odejmowania jest równy (std::ptrdiff_t)0.
Te operatory arytmetyki wskaźników pozwalają wskaźnikom spełniać wymagania LegacyRandomAccessIterator.
W rozdzielczości przeciążania przeciwko operatorom zdefiniowanym przez użytkownika, dla każdej pary promowanych typów arytmetycznych L
i R
oraz dla każdego typu obiektu T
, następujące sygnatury funkcji uczestniczą w rozdzielczości przeciążania:
gdzie LR
jest wynikiem zwykłej konwersji arytmetycznej na . konwersji arytmetycznej na L
i R
#include <iostream>int main(){ char c = 2; unsigned int un = 2; int n = -10; std::cout << " 2 + (-10), where 2 is a char = " << c + n << '\n' << " 2 + (-10), where 2 is unsigned = " << un + n << '\n' << " -10 - 2.12 = " << n - 2.12 << '\n'; char a = {'a', 'b', 'c', 'd'}; char* p = &a; std::cout << "Pointer addition examples: " << *p << *(p + 2) << *(2 + p) << *(p - 1) << '\n'; char* p2 = &a; std::cout << "Pointer difference: " << p2 - p << '\n';}
Wyjście:
2 + (-10), where 2 is a char = -8 2 + (-10), where 2 is unsigned = 4294967288 -10 - 2.12 = -12.12Pointer addition examples: bddaPointer difference: 3
Operatory multiplikatywne
Binarne wyrażenia operatorów arytmetycznych multiplikatywnych mają postać
lhs * rhs |
(1) | ||||||||
lhs / rhs |
(2) | ||||||||
lhs % rhs |
(3) | ||||||||
Dla wszystkich trzech operatorów, zwykłe konwersje arytmetyczne są wykonywane na obu operandach i określają typ wyniku.
Operator binarny * wykonuje mnożenie swoich operandów (po zwykłych konwersjach arytmetycznych), z wyjątkiem tego, że dla mnożenia zmiennoprzecinkowego,
- mnożenie NaN przez dowolną liczbę daje NaN
- mnożenie nieskończoności przez zero daje NaN i podnoszona jest wartość FE_INVALID
Operator binarny / dzieli pierwszy operand przez drugi (po zwykłych konwersjach arytmetycznych).
Dla operandów całkowitych daje iloraz algebraiczny.
Licznik jest zaokrąglany w kierunku określonym przez implementację. |
(do C++11) |
Ci iloraz jest obcinany w kierunku zera (część ułamkowa jest odrzucana). |
(od C++11) |
Jeśli drugi operand jest zerem, zachowanie jest niezdefiniowane, z wyjątkiem tego, że jeśli ma miejsce dzielenie zmiennoprzecinkowe, a typ obsługuje arytmetykę zmiennoprzecinkową IEEE (patrz std::numeric_limits::is_iec559), to:
- jeśli jeden operand jest NaN, wynikiem jest NaN
- dzielenie niezerowej liczby przez ±0.0 daje poprawnie podpisaną nieskończoność i podnoszona jest wartość FE_DIVBYZERO
- dzielenie 0.0 przez 0.0 daje NaN i podnoszona jest wartość FE_INVALID
Operator binarny % daje resztę z dzielenia liczby całkowitej pierwszego operandu przez drugi (po zwykłych konwersjach arytmetycznych; zauważ, że typy operandów muszą być typami całkowitymi). Jeśli iloraz a/b
jest reprezentowalny w typie wynikowym, to (a/b)*b + a%b == a. Jeśli drugi operand jest zerem, to zachowanie jest niezdefiniowane. Jeśli iloraz a/b
nie jest reprezentowalny w typie wynikowym, zachowanie zarówno a/b
jak i a%b
jest niezdefiniowane (to znaczy INT_MIN%-1 jest niezdefiniowane w systemach 2’s complement)
Uwaga: Do C++11, jeśli jeden lub oba operandy operatora binarnego % były ujemne, znak reszty był definiowany przez implementację, ponieważ zależy od kierunku zaokrąglania przy dzieleniu liczb całkowitych. Funkcja std::div zapewniała dobrze zdefiniowane zachowanie w takim przypadku.
Uwaga: dla reszt zmiennoprzecinkowych, zobacz std::remainder i std::fmod.
W rozdzielczości przeciążania przeciwko operatorom zdefiniowanym przez użytkownika, dla każdej pary promowanych typów arytmetycznych LA
i RA
oraz dla każdej pary promowanych typów całkowych LI
i RI
następujące sygnatury funkcji uczestniczą w rozdzielczości przeciążania:
gdzie LRx
jest wynikiem zwykłej konwersji konwersji arytmetycznych na Lx
i Rx
#include <iostream>int main(){ char c = 2; unsigned int un = 2; int n = -10; std::cout << "2 * (-10), where 2 is a char = " << c * n << '\n' << "2 * (-10), where 2 is unsigned = " << un * n << '\n' << "-10 / 2.12 = " << n / 2.12 << '\n' << "-10 / 21 = " << n / 21 << '\n' << "-10 % 21 = " << n % 21 << '\n';}
Wyjście:
2 * (-10), where 2 is a char = -202 * (-10), where 2 is unsigned = 4294967276-10 / 2.12 = -4.71698-10 / 21 = 0-10 % 21 = -10
Bitowe operatory logiczne
Wyrażenia bitowych operatorów arytmetycznych mają postać
~ rhs |
(1) | ||||||||
lhs & rhs |
(2) | ||||||||
lhs | rhs |
(3) | ||||||||
lhs ^ rhs |
(4) | ||||||||
Wynikiem operatora~ jest bitowa wartość NOT (dopełnienie jedynki) argumentu (po promocji). Wynikiem operatora& jest bitowa wartość AND operandów (po zwykłych konwersjach arytmetycznych). Wynikiem operatora| jest wartość bitowa OR operandów (po zwykłej konwersji arytmetycznej). Wynikiem operatora^ jest bitowa wartość XOR operandów (po zwykłych konwersjach arytmetycznych)
W rozwiązywaniu przeciążeń względem operatorów zdefiniowanych przez użytkownika, dla każdej pary promowanych typów całkowych L
i R
w rozwiązywaniu przeciążeń uczestniczą następujące sygnatury funkcji:
gdzie LR
jest wynikiem zwykłej konwersji konwersji arytmetycznej na L
i R
#include <iostream>int main(){ std::cout << std::hex << std::showbase; uint16_t mask = 0x00f0; uint32_t a = 0x12345678; std::cout << "Value: " << a << " mask: " << mask << '\n' << "Setting bits: " << (a | mask) << '\n' << "Clearing bits: " << (a & ~mask) << '\n' << "Selecting bits: " << (a & mask) << '\n';}
Wyjście:
Value: 0x12345678 mask: 0xf0Setting bits: 0x123456f8Clearing bits: 0x12345608Selecting bits: 0x70
Operatory przesunięcia bitowego
Wyrażenia bitowych operatorów przesunięcia mają postać
lhs << rhs |
(1) | ||||||||
lhs >> rhs |
(2) | ||||||||
Typem zwracanym jest typ lewego operandu po promocjach integralnych.
Dla unsigned Dla podpisanych i nieujemnych Dla ujemnych Dla niepodpisanych Dla ujemnych |
(do C++20) |
Wartość Wartością |
(od C++20) |
W każdym przypadku, jeśli wartość prawego operandu jest ujemna lub jest większa lub równa liczbie bitów w promowanym lewym operandzie, zachowanie jest niezdefiniowane.
W rozdzielczości przeciążania przeciwko operatorom zdefiniowanym przez użytkownika, dla każdej pary promowanych typów integralnych L
i R
, następujące sygnatury funkcji uczestniczą w rozdzielczości przeciążania:
#include <iostream>enum {ONE=1, TWO=2};int main(){ std::cout << std::hex << std::showbase; char c = 0x10; unsigned long long ull = 0x123; std::cout << "0x123 << 1 = " << (ull << 1) << '\n' << "0x123 << 63 = " << (ull << 63) << '\n' // overflow in unsigned << "0x10 << 10 = " << (c << 10) << '\n'; // char is promoted to int long long ll = -1000; std::cout << std::dec << "-1000 >> 1 = " << (ll >> ONE) << '\n';}
Output:
0x123 << 1 = 0x2460x123 << 63 = 0x80000000000000000x10 << 10 = 0x4000-1000 >> 1 = -500
Biblioteka standardowa
Operatory arytmetyczne są przeciążone dla wielu typów biblioteki standardowej.
Operatory arytmetyczne jednoargumentowe
(public member function of
std::chrono::duration<Rep,Period>
)
(function template)
(public member function of
std::valarray<T>
) . Operatory addytywne
(szablon funkcji)
(szablon funkcji)
year_month_day
i pewną liczbę lat lub miesięcy (funkcja członka publicznego
std::chrono::year_month_day
)
(szablon funkcji)
(funkcja członka publicznego
std::reverse_iterator<Iter>
)
(funkcja członka publicznego
std::move_iterator<Iter>
)
(szablon funkcji)
(szablon funkcji)
Operatory multiplikatywne
(szablon funkcji)
(szablon funkcji)
(szablon funkcji)
Bitowe operatory logiczne
(funkcja członka publicznego
std::bitset<N>
)
(szablon funkcji)
(funkcja członka publicznego
std::valarray<T>
)
(szablon funkcji)
Operatory przesunięcia bitowego
(szablon funkcji)
(funkcja członka publicznego
std::bitset<N>
) Operatory wstawiania/wyciągania strumienia
Przez całą bibliotekę standardową, operatory przesunięcia bitowego są powszechnie przeciążane strumieniem I/O (std::ios_base& lub jedną z klas pochodnych od niego) zarówno jako lewy operand, jak i typ zwracany. Takie operatory są znane jako operatory wstawiania strumienia i wyciągania strumienia:
(funkcja członka publicznego
std::basic_istream<CharT,Traits>
)
(szablon funkcji)
(funkcja członka publicznego
std::basic_ostream<CharT,Traits>
)
(szablon funkcji)
(szablon funkcji)
(szablon funkcji)
(szablon funkcji)
(function template)
(function template)
Defect reports
Następujące raporty o wadach zmieniających zachowanie zostały zastosowane z mocą wsteczną do wcześniej opublikowanych standardów C++.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 1457 | C++98 | shifting the leftmost 1 bit of a positive signed value into the sign bit was UB |
made well-zdefiniowane |
Zobacz także
Pierwszeństwo operatorów
Przeciążanie operatorów
Operatory wspólne | ||||||
---|---|---|---|---|---|---|
przypisanie | . increment decrement |
arytmetyczne | logiczne | porównania | member access |
inne |
a = b |
++a |
+a |
!a |
a == b |
a |
a(…) |
Operatory specjalne | ||||||
static_cast konwertuje jeden typ na inny powiązany typ |