#include <thread>
#include <iostream>

class cl1;
class cl2;


class cl2 {
public:
    int y;
    cl2(int y) : y(y)   {}          		//ctor
};

class cl1 {
public:
    int x;
    cl1(int x) : x(x) {}             	 //ctor
    cl1(cl2& ob1) : x(ob1.y * 2) {}      //ctor for automatic conversion of cl2& to cl1, x = y*2
};

void do_work_with_cl(cl1 ob) {				//This works as usual by actually copying the object through the copy constructor
    std::cout << "The x of ob is " << ob.x << std::endl;
}

void do_work_with_cl_rref(cl1&& ob) {		//I guess this works because it takes an rvalue and the automatic
                                            //conversion ctor of cl1 does just that
    std::cout <<"Inside the function that takes cl1 as rvalue, x of ob is"  << ob.x << std::endl;
}

void do_work_with_cl_lref(cl1& ob) {		//This doesn't work as ob is non-const lvalue reference
    std::cout << "lvalue referenced but the object created through implicit conversion is temporary(i.e rvalue)" << std::endl;
}


int main() {
    //Normal non-threaded calls
    cl2 ob(100);				//create a cl2 object
    do_work_with_cl(ob);			//This is ok
    do_work_with_cl_rref(ob);	//This too works
    //do_work_with_cl_lref(ob)	//This fails, as suspected

    std::cout << "Thread part" << std::endl;

    //Now calling the functions through a thread
    std::thread t1(do_work_with_cl_rref, ob);	//Thought this could work here, but doesn't
                                                //The other functions also don't work, but I can understand why.
    t1.join();
}
