#include <iostream>

class Int
{
    int n_;

public:
    explicit Int(int n) noexcept : n_(n) { std::cout << "Int(" << n_ << ")\n"; }

    Int(Int const & rhs) : n_(rhs.n_) { std::cout << "Int(Int const &)[" << n_ << "]\n"; }
    Int(Int && rhs)      : n_(rhs.n_) { std::cout << "Int(Int &&)     [" << n_ << "]\n"; }

    ~Int() { std::cout << "~Int()[" << n_ << "]\n"; }

    Int & operator+=(Int const & rhs) { n_ += rhs.n_; return *this; }
    Int & operator+=(Int && rhs)      { n_ += rhs.n_; return *this; }

#ifdef LAZY
    Int operator+(Int rhs) { return Int(*this) += std::move(rhs); }
#else
    Int operator+(Int const & rhs) { Int result(*this); result += rhs; return result; }
    Int operator+(Int && rhs) { Int result(*this); result += std::move(rhs); return result; }
#endif
};


int main()
{
    auto x = Int(10) + Int(20) + Int(30);
}
