0

On one hand, in general, a temporary object is destroyed at the end of the full-expression that it is part of.

To quote the draft of the standard N4140 Section 12.2:

Temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created.

On the other hand, consider Case 1

#include <iostream>
#include <memory>

using std::cout;
using std::endl;
using std::shared_ptr;

void process(shared_ptr<int> p)
{
    std::cout << p.use_count() << std::endl;
}

int main()
{
    process(shared_ptr<int>(new int));
    return 0;
}

Or even simpler, as in Case 2

using std::cout;
using std::endl;
using std::shared_ptr;

int main()
{
    cout << shared_ptr<int>(shared_ptr<int>(new int)).use_count() << endl;
    return 0;
}

In either case, the output is 1. Not 2.

I feel somewhat confused at the output, and appreciate anyone who may offer some explanation.

My understanding for Case 1 is that shared_ptr<int>(new int) is a temporary object passed to process as an argument. According to the standard, it should not be destroyed before process makes its return. If that were the case, then the parameter p, which is initialized from the temporary, should have a use_count of 2 at the time of output, because at that time there are 2 objects managed by the shared_ptr.

My understanding for Case 2 follows the same logic.

It seems that there must be some mistakes in my understanding. Could someone please point them out? Thanks very much.

Note: There are several solved questions related to mine, but after reading them I am still confused. You may read this one for your reference.

aafulei
  • 2,085
  • 12
  • 27

1 Answers1

3

The expression shared_ptr<int>(shared_ptr<int>(new int)) only creates one temporary, it is equivalent to shared_ptr<int>(new int).

You can see what you expect using this code:

shared_ptr<int> f(shared_ptr<int>&& x){return x;}
int main()
{
    //N1:
    cout << shared_ptr<int>(f(shared_ptr<int>(new int))).use_count() << endl;
    return 0;
}

Following user1095108 proposal:

shared_ptr<int> f(shared_ptr<int>&& x){return x;}
int main()
{
    //also prints 2, because equivalent to N1
    cout << f(shared_ptr<int>(new int)).use_count() << endl;

    //prints 3:
    cout << shared_ptr<int>(f(f(shared_ptr<int>(new int)))).use_count() << endl;

    //also prints 3:
    cout << f(f(shared_ptr<int>(new int))).use_count() << endl;
    return 0;
}
Oliv
  • 17,610
  • 1
  • 29
  • 72