I am learning about copy elision and tried out something to learn about it. But there is something unexpected happening with the below code:
template<typename T>
class AutoPtr
{
    T* m_ref;
    public:
    AutoPtr(T* ref)
    {
        printf("Cons called\n");
        m_ref = ref;
    }
    AutoPtr(const AutoPtr& autoPtr)
    {
        printf("Copy called\n");
        m_ref = autoPtr.m_ref;
    }
    ~AutoPtr()
    {
        delete m_ref;
    }
};
class Reference
{
    public:
        Reference()
        {
            printf("Reference created\n");
        }
        ~Reference()
        {
            printf("Reference deleted\n");
        }
};
AutoPtr<Reference> generateRes()
{
    Reference *ref = new Reference();
     //Scenario 1
    //AutoPtr<Reference> temp{ref};
    //return temp;
    //Scenario 2
    return AutoPtr<Reference>{ref};
}                                                                                                                       
int main()
{
    AutoPtr<Reference> obj1 = generateRes();
    return 0;
}
In the above code, I am trying 2 scenarios.
- Initializing a temp AutoPtr object and then returning it. Here, constructor is called when temp is initialized. But in the main function, when obj1 is initialized, constructor is not called.
- Directly returning temporary object. Here in the main function, obj1 is initialized and constructor is called.
Why doesn't scenario 1 call constructor for obj1? Is it some compiler optimization? I know that copy elision has happened and copy constructor is not called, but why is the normal constructor not called twice?
 
    