#include <iostream>
using namespace std;

class Pt {
public:
Pt() {
    std::cout << "default constructor" << std::endl;
}

Pt(const Pt& rvalue) {
    std::cout << "copy constructor" << std::endl;
}

Pt(const Pt&& rvalue) {
    std::cout << "move constructor" << std::endl;
}

Pt& operator=(const Pt& rvalue) {
    std::cout << "copy assignment" << std::endl;
    return *this;
}

Pt& operator=(const Pt&& rvalue) {
    std::cout << "move assignment" << std::endl;
}

~Pt() {
    std::cout << "~Pt" << std::endl;
}

//a function to call in order to prevent getting optimized out
void test() {
	std::cout << " " << std::endl;
}
};

int main() {
{
     //here the compiler thinks that we declare a function
     std::cout << "step 1" << std::endl;
     Pt pt();
}
{
     //here the compiler calls a default constructor
     std::cout << "step 2" << std::endl;
     Pt pt;
}
{
     //here the compiler calls a default constructor too
     std::cout << "step 3" << std::endl;
     Pt pt = Pt();
}

{
    //here the compiler calls a copy constructor and doesn't call the default constructor prior to that
    // O_o
    std::cout << "step 4" << std::endl;
    Pt pt = pt;
}
return 0;
}