#include <iostream>
using namespace std;

// Оголошення шаблонного класу Vec2D.
// <typename T> означає, що координати x та y можуть бути будь-якого типу (int, double, float тощо).
template <typename T>
class Vec2D {
    T x, y; // координати вектора
public:
    // Конструктор за замовчуванням: x=0, y=1
    Vec2D(): x(0), y(1) {
        cout << "Constructor " << x << " " << y << endl;
    }

    // Конструктор з параметрами
    Vec2D(T x, T y): x(x), y(y) {
        cout << "Constructor " << x << " " << y << endl;
    }

    // Деструктор: викликається при знищенні об'єкта
    ~Vec2D() {
        cout << "Destructor " << x << " " << y << endl;
    }

    // Перевантаження оператора присвоєння "="
    Vec2D<T>& operator=(const Vec2D<T>& right) {
        x = right.x;
        y = right.y;
        return *this;
    }

    // Перевантаження оператора "+=" для додавання константи до координат
    Vec2D<T>& operator+=(T c) {
        x += c; y += c;
        return *this;
    }

    // Постфіксний інкремент (obj++)
    Vec2D<T>& operator++(int) {
        x++; y++;
        return *this;
    }

    // Префіксний інкремент (++obj)
    Vec2D<T>& operator++() {
        x++; y++;
        return *this;
    }

    // Перевантаження оператора "+" для додавання двох векторів
    Vec2D<T> operator+(const Vec2D<T>& right) {
        return Vec2D<T>(x + right.x, y + right.y);
    }

private:
    // Дружня функція для виведення вектора у потік
    template <typename T1> 
    friend ostream& operator<<(ostream& os, const Vec2D<T1>& a);  
};

// Реалізація оператора виведення <<
template <typename T>
ostream& operator<<(ostream& os, const Vec2D<T>& a) {  
    os << a.x << ' ' << a.y << endl;  
    return os;  
}

int main() {
    Vec2D<double> a(1,2);   // створення вектора з координатами (1,2)
    Vec2D<double> b;        // створення вектора за замовчуванням (0,1)
    ++b;                    // префіксний інкремент: (0,1) → (1,2)
    cout << b;              // вивід координат вектора b
    b = a += 100;           // до a додається 100 → (101,102), результат присвоюється b
    a + b;                  // створюється тимчасовий вектор (202,204), але не використовується
    cout << b << endl;      // вивід координат b (101,102)
    return 0;
}


