Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why copy constructor is getting called?

Tags:

c++

c++11

I have the following piece of code and there are a couple of things that bother me the most:

  1. At what point in time does original constructor call happen?
  2. Under which circumstances, the copy constructor is getting called?
#include <iostream>
#include <functional>

class Samp {
    char str[10] = "Default";
public:
    Samp(char s[]) { strcpy(str, s); printf("Constructor\n"); }
    Samp(const Samp& s) { printf("Copy Constructor\n"); }
    ~Samp() { printf("Destructor\n"); }

    char* out() {
        return str;
    }

    friend std::ostream& operator<<(std::ostream& stream, const Samp& s) {
        stream << s.str;

        return stream;
    }
};

void output(Samp s) {
    std::cout << s << std::endl;
}

int main(int argc, const char * argv[]) {
    std::function<void(Samp s)> o;
    o = output;

    o((char*)"Hello");

    return 0;
}

On execution, the program provides the following output

Constructor
Copy Constructor
Default
Destructor
Destructor
Program ended with exit code: 0

enter image description here

like image 369
nakhodkin Avatar asked May 13 '26 06:05

nakhodkin


2 Answers

The arguments to a std::function invocation are passed by perfect forwarding through to the callable object stored inside the std::function object.

So the behaviour of o(args...) is not the same as output(args...). Instead it is the same as:

output( std::forward<Args...>(args...) );

or in this concrete example,

output( std::forward<Samp>( (char *)"Hello" ) );

In this example we see that "perfect" forwarding is not so perfect, as this code has slightly different behaviour to output( (char *)"Hello" ); .

The signature of the chosen overload for forward is Samp&& forward(Samp&& arg);. So there must be a temporary materialized for the arg to bind to for the function call tostd::forward; that is the "Constructor" that you see.

Then the "Copy constructor" is initialization of the output function's parameter from the return value of std::forward. That could be a move operation, if Samp had a move-constructor.

like image 144
M.M Avatar answered May 14 '26 22:05

M.M


Constructor and Copy of you class called in one place basicly. When you use youre function its create Samp S by construct and then copy it to void fnc.

like image 24
Dies_Irae Avatar answered May 14 '26 22:05

Dies_Irae