samedi 13 novembre 2021

Program uses Copy Constructor instead of Move Constructor

I am trying to understand the concept of copy and move constructors in C++. And so trying out different examples. One such example whose output i am unable to understand is given below:

#include <iostream>
#include <vector>
using namespace std;
struct NAME 
{
    NAME()
    {
        std::cout<<"default"<<std::endl;
    }
    NAME(const NAME& )
    {
        std::cout<<"const copy"<<std::endl;
    }
    NAME(NAME& )
    {
        std::cout<<"nonconst copy"<<std::endl;
    }
    NAME(NAME &&)
    {
        std::cout<<"move"<<std::endl;
    }
};
void foo(std::pair<std::string, NAME> ) 
{
    
}
void foo2(std::vector<std::pair<std::string, NAME>> )
{
}
int main()
{
    foo(std::make_pair("an", NAME())); //prints default --> move --> move
    std::cout << "----------------------------------------"<<std::endl;
    
    foo({"an", NAME()});               //prints default --> move
    std::cout << "----------------------------------------"<<std::endl;
    
    foo2();            //prints default --> move --> const copy
    std::cout << "----------------------------------------"<<std::endl;
    return 0;
}

Case 1: For foo(std::make_pair("an", NAME()));

Output

default
move
move

This is what i think is happening.

Step 1. A temporary of type NAME() is craeted because we've passed it to std::make_pair using the NAME()'s default constructor.

Step 2. One of the std::make_pair's constructor is used which forwards(moves) the the temporary that was created in the 1st step. So NAME()'s move constructor.

Step 3. Finally, since the argument to foo is passed by value, so the std::pair that was created in step 2 is "moved"(not "copied"?) which in turn "moves" the NAME temporary one last time.

Case 2: For foo({"an", NAME()});

Output

default
move

Step 1. A temporary NAME is created.

Step 2. This time since we do not have std::make_pair, std::pair's initializer list constructor(if any) is used to "move" the temporary created in step 1.

Case 3: For foo2();

Output

default
move
const copy

I have no idea why copy constructor is used instead of move constructor and also why the const version is used instead of nonconst version of copy constructor.

Are my explanation correct. Please correct me where i am wrong in any of my explanation steps in detail.

Aucun commentaire:

Enregistrer un commentaire