I was trying out a program on universal references by applying std::move and std::forward on them. Until today I assumed that both were the same but in this very program (given below) the output amazed me.
#include <iostream>
#include <string>
#include <utility>
using namespace std;
class X
{
    string take="";
    public:
    template<class T>
    void pass1 (T &&str)   // str is a universal reference as it can bind to anything, both rvalue and lvalue references
    {
        take=move(str);
    }
    template<class T>
    void pass2 (T &&str)
    {
        take=forward<T>(str);
    }
    void show()
    {
        cout<<"take = "<<take<<"\n";
    }
}obj;
int main()
{
    cout<<"using move on universal reference:-\n";
    string str="he is there";
    cout<<"str = "<<str<<'\n';
    obj.pass1(str);
    obj.show();
    if (str.empty())
    cout<<"str is empty\n\n";
    else
    cout<<"str isnt empty\n\n";
    cout<<"using forward on universal reference:-\n";
    str="he was there";
    cout<<"str = "<<str<<'\n';
    obj.pass2(str);
    obj.show();
    if (str.empty())
    cout<<"str is empty\n\n";
    else
    cout<<"str isnt empty\n\n";
    return 0;
}
Output:
using move on universal reference:-
str = he is there
take = he is there
str is empty
using forward on universal reference:-
str = he was there
take = he was there
str isnt empty
*/
My questions are:
- Why are the outputs different?
- Don't moveandforwardwork similarly? How are they working differently (in context with the above code)?
 
     
     
     
     
     
    