---------------
x+y*z
---------------
pomn y przez z i dodaj wynik do x
---------------
class complex {  // bardzo uproszczona reprezentacja liczb zespolonych
    double re, im;
public:
    complex(double r, double i) :re{r}, im{i} { }
    complex operator+(complex);
    complex operator*(complex);
};
---------------
void f()
{
    complex a = complex{1,3.1};
    complex b {1.2, 2};
    complex c {b};

    a = b+c;
    b = b+c*a;
    c=a*b+complex(1,2);
}
---------------
void g(complex a, complex b)
{
    a = {1,2};          // OK: prawa strona przypisania
    a += {1,2};         // OK: prawa strona przypisania
    b = a+{1,2};        // bd skadni
    b = a+complex{1,2}; // OK
    g(a,{1,2});         // OK: argument funkcji jest uwaany za inicjator
    {a,b} = {b,a};      // bd skadni
}
---------------
+        -       *       /        %        ^        &
|        ~       !       =        <        >        +=
-=      *=      /=      %=        ^=      &=        |=
<<      >>      >>=     <<=       ==      !=        <=
>=      &&      ||      ++        --      ->*       ,
->      []      ()      new       new[]   delete    delete[]

---------------
void f(complex a, complex b)
{
    complex c=a+b;              // skrt
    complex d = a.operator+(b); // bezporednie wywoanie
}
---------------
class X {
public:
    void operator+(int);
    X(int);
};

void operator+(X,X);
void operator+(X,double);

void f(X a)
{
    a+1;    // a.operator+(1)
    1+a;    // ::operator+(X(1),a)
    a+1.0;  // ::operator+(a,1.0)
}
---------------
class X {
public: // skadowe (z niejawnym wskanikiem this):
    X* operator&();    // przedrostkowy jednoargumentowy & (adres)
    X operator&(X);    // dwuargumentowy & (i)
    X operator++(int); // inkrementacja przyrostkowa (zobacz 19.2.4)
    X operator&(X,X);  // bd: trjargumentowy
    X operator/();     // bd: jednoargumentowy /
};

// funkcje nieskadowe:

X operator-(X);       // przedrostkowy jednoargumentowy minus
X operator-(X,X);     // dwuargumentowy minus
X operator--(X&,int); // przyrostkowa dekrementacja
X operator-();        // bd: brak argumentu
X operator-(X,X,X);   // bd: trjargumentowy
X operator%(X);       // bd: jednoargumentowy %
---------------
class X {
public:
    //...
    void operator=(const X&) = delete;
    void operator&() = delete;
    void operator,(const X&) = delete;
    //...
};

void f(X a, X b)
{
    a=b;  // bd: brak operator=()
    &a;   // bd: brak operator&()
    a,b;  // bd: brak operator,()
}
---------------
enum Day { nie, pon, wt, r, czw, pi, sob };

Day& operator++(Day& d)
{
    return d = (sat==d) ? sun : static_cast<Day>(d+1);
}
---------------
void Point::operator+=(Point delta); // przekazanie przez warto
---------------
Matrix operator+(const Matrix&, const Matrix&); // przekazanie przez sta referencj
---------------
Matrix operator+(const Matrix& a, const Matrix& b) // zwrot przez warto
{
    Matrix res {a};
    return res+=b;
}
---------------
Matrix& Matrix::operator+=(const Matrix& a) // zwrot przez referencj
{
    if (dim[0]!=a.dim[0] || dim[1]!=a.dim[1])
        throw std::exception("Niepoprawny argument");

    double* p = elem;
    double* q = a.elem;
    double* end = p+dim[0]*dim[1];
    while (p!=end)
        *p++ +=*q++;
    return *this;
}
---------------
namespace std { // uproszczona przestrze std

    class string {
        //...
    };

    class ostream {
        //...
        ostream& operator<<(const char*);         // wysya na wyjcie acuch w stylu C
    };

    extern ostream cout;

    ostream& operator<<(ostream&, const string&); // wysya na wyjcie std::string
} // przestrze std

int main()
{
    const char* p = "Witaj,";
    std::string s = "wiecie";
    std::cout << p << ", " << s << "!\n";
}
---------------
using namespace std;
---------------
std::cout << p
---------------
std::cout.operator<<(p)
---------------
std::cout << s
---------------
operator<<(std::cout,s)
---------------
std::operator<<(std::ostream&, const std::string&)
---------------
X operator!(X);

struct Z {
    Z operator!();                      // nie ukrywa operatora ::operator!()
    X f(X x) { /*...*/ return !x; }     // wywouje ::operator!(X)
    int f(int x) { /*...*/ return !x; } // wywouje wbudowany operator ! dla int
};
---------------
void f()
{
    complex a {1,2};
    complex b {3};
    complex c {a+2.3};
    complex d {2+b};
    b=c*2*c;
}
---------------
class complex {
    double re, im;
public:
    complex& operator+=(complex a);  // wymaga dostpu do reprezentacji
    //...
};

complex operator+(complex a, complex b)
{
    return a += b; // dostp do reprezentacji przez +=
}
---------------
void f(complex x, complex y, complex z)
{
    complex r1 {x+y+z}; // r1 = operator+(operator+(x,y),z)
    complex r2 {x};     // r2 = x
    r2 += y;            // r2.operator+=(y)
    r2 += z;            // r2.operator+=(z)
}
---------------
inline complex& complex::operator+=(complex a)
{
    re += a.re;
    im += a.im;
    return *this;
}
---------------
class complex {
    double re, im;
public:
    complex& operator+=(complex a)
    {
        re += a.re;
        im += a.im;
        return *this;
    }

    complex& operator+=(double a)
    {
        re += a;
        return *this;
    }

    //...
};
---------------
complex operator+(complex a, complex b)
{
    return a += b; // wywouje complex::operator+=(complex)
}

complex operator+(complex a, double b)
{
    return {a.real()+b,a.imag()};
}

complex operator+(double a, complex b)
{
    return {a+b.real(),b.imag()};
}
---------------
void f(complex x, complex y)
{
    auto r1 = x+y; // wywouje operator+(complex,complex)
    auto r2 = x+2; // wywouje operator+(complex,double)
    auto r3 = 2+x; // wywouje operator+(double,complex)
    auto r4 = 2+3; // wbudowane dodawanie liczb cakowitych
}
---------------
complex b {3}; // powinno znaczy b.re=3, b.im=0

void comp(complex x)
{
    x=4; // powinno znaczy x.re=4, x.im=0
    //...
}
---------------
class complex {
    double re, im;
public:
    complex(double r) :re{r}, im{0} { } // tworzy warto typu complex z wartoci typu double
    //...
};
---------------
complex b {3};
---------------
complex b {3,0};
---------------
class complex {
    double re, im;
public:
    complex() : re{0}, im{0} { }
    complex(double r) : re{r}, im{0} { }
    complex(double r, double i) : re{r}, im{i} { }
    //...
};
---------------
class complex {
    double re, im;
public:
    complex(double r =0, double i =0) : re{r}, im{i} { }
    //...
};
---------------
void f()
{
    complex z;
    complex x {1,2};
    complex y {x}; // y rwnie ma warto {1,2}
    z=x;           // z rwnie ma warto {1,2}
}
---------------
complex operator+(complex,complex);
complex operator+(complex,double);
complex operator+(double,complex);
//...
---------------
bool operator==(complex,complex);

void f(complex x, complex y)
{
    x==y; // oznacza operator==(x,y)
    x==3; // oznacza operator==(x,complex(3))
    3==y; // oznacza operator==(complex(3),y)
}
---------------
void g(complex z)
{
    3+z;             // OK: complex(3)+z
    3.operator+=(z); // bd: 3 nie jest obiektem klasy
    3+=z;            // bd: 3 nie jest obiektem klasy
}
---------------
complex x {4,5}
complex z {sqr t(x)+={1,2}}; // jak tmp=sqrt(x), tmp+={1,2}
---------------
class complex {
public:
    constexpr complex(double r =0, double i =0) : re{r}, im{i} { }
    //...
}
---------------
complex z1 {1.2,12e3};
constexpr complex z2 {1.2,12e3};  // gwarantowana inicjacja w czasie kompilacji
---------------
constexpr complex<double> operator "" i(long double d) // litera czci urojonej
{
    return {0,d};                                      // complex jest typem literaowym
}
---------------
complex z1 {1.2+12e3i};

complex f(double d)
{
    auto x {2.3i};
    return x+sqrt(d+12e3i)+12e3i;
}
---------------
complex z1 {1.2,12e3};

complex f(double d)
{
    complex x {0,2.3};
    return x+sqrt(complex{d,12e3})+complex{0,12e3};
}
---------------
class complex {
    double re, im;
public:
    constexpr double real() const { return re; }
    constexpr double imag() const { return im; }

    void real(double r) { re = r; }
    void imag(double i) { im = i; }
    //...
};
---------------
inline bool operator==(complex a, complex b)
{
    return a.real()==b.real() && a.imag()==b.imag();
}
---------------
class complex {
    double re, im;
public:
    constexpr complex(double r =0, double i =0) : re(r), im(i) { }

    constexpr double real() const { return re; }
    constexpr double imag() const { return im; }

    void real(double r) { re = r; }
    void imag(double i) { im = i; }

    complex& operator+=(complex);
    complex& operator+=(double);

    // -=, *= oraz /=
};
---------------
complex operator+(complex,complex);
complex operator+(complex,double);
complex operator+(double ,complex);

// binarne -, * oraz /

complex operator-(complex); // jednoargumentowy minus
complex operator+(complex); // jednoargumentowy plus

bool operator==(complex,complex);
bool operator!=(complex,complex);

istream& operator>>(istream&,complex&);  // wejcie
ostream& operator<<(ostream&,complex);   // wyjcie
---------------
complex polar(double rho, double theta);
complex conj(complex);

double abs(complex);
double arg(complex);
double norm(complex);

double real(complex);  // udogodnienie notacyjne
double imag(complex);  // udogodnienie notacyjne
---------------
complex acos(complex);
complex asin(complex);
complex atan(complex);
//...
---------------
class Tiny {
    char v;
    void assign(int i) { if (i&~077) throw Bad_range(); v=i; }
public:
    class Bad_range { };

    Tiny(int i) { assign(i); }
    Tiny& operator=(int i) { assign(i); return *this; }

    operator int() const { return v; } // konwersja na int
};
---------------
Tiny::operator int() const { return v; }     // dobrze
int Tiny::operator int() const { return v; } // le
---------------
int main()
{
    Tinyc1=2;
    Tiny c2 = 62;
    Tiny c3 = c2-c1; // c3 = 60
    Tiny c4 = c3;    // bez sprawdzania zakresu (nie jest potrzebne)
    int i = c1+c2;   // i=64

    c1 = c1+c2;      // bd zakresu: c1 nie moe zawiera wartoci 64
    i = c3-64;       // i=-4
    c2 = c3-64;      // bd zakresu: c2 nie moe zawiera wartoci -4
    c3 = c4;         // bez sprawdzania zakresu (nie jest potrzebne)
}
---------------
while (cin>>x)
    cout<<x;
---------------
int operator+(Tiny,Tiny);
void f(Tiny t, int i)
{
    t+i; // bd niejednoznacznoci: operator+(t,Tiny(i)) czy int(t)+i?
}
---------------
template <typename T, typename D = default_delete<T>>
class unique_ptr {
public:
    //...
    explicit operator bool() const noexcept;  // czy *this zawiera wskanik (nie bdcy nullptr)?
    //...
};
---------------
void use(unique_ptr<Record> p, unique_ptr<int> q)
{
    if (!p)      // OK: chcemy tego
        throw Invalid_unique_ptr{};

    bool b = p;  // bd: podejrzane uycie
    int x = p+q; // bd: na pewno tego nie chcemy
}
class X { /*...*/ X(int); X(const char*); };
class Y { /*...*/ Y(int); };
class Z { /*...*/ Z(X); };

X f(X);
Y f(Y);

Z g(Z);

void k1()
{
    f(1);         // bd niejednoznacznoci: f(X(1)) czy f(Y(1))?
    f(X{1});      // OK
    f(Y{1});      // OK

    g("Mack");    // bd: potrzebne s dwie konwersje zdefiniowane przez uytkownika; 
                  // g(Z{X{"Mack"}}) nie jest sprawdzane
    g(X{"Doc"});  // OK: g(Z{X{"Doc"}})
    g(Z{"Suzy"}); // OK: g(Z{X{"Suzy"}})
}
---------------
class XX { /*...*/ XX(int); };

void h(double);
void h(XX);

void k2()
{
    h(1); // h(double{1}) czy h(XX{1})? h(double{1})!
}
---------------
class Quad {
public:
    Quad(double);
    //...
};

Quad operator+(Quad,Quad);

void f(double a1, double a2)
{
    Quad r1 = a1+a2;       // dodawanie zmiennoprzecinkowe podwjnej precyzji
    Quad r2 = Quad{a1}+a2; // wymuszenie arytmetyki poczwrnej precyzji
}
---------------
class Real {
public:
    operator double();
    operator int();
    //...
};

void g(Real a)
{
    double d = a; // d = a.double();
    int i = a;    // i = a.int();

    d=a;          // d = a.double();
    i=a;          // i = a.int();
}