Reputation: 1465
I have the following piece of code and there are a couple of things that bother me the most:
#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
Upvotes: 3
Views: 227
Reputation: 141544
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.
Upvotes: 5
Reputation: 82
void output(Samp s)
This is the problem. This function pass object by value. When you call
o((char*)"Hello")
, it creates an temporary Samp object by default constructor, and create another new object by copy constructor to pass to the function.
Upvotes: 2
Reputation: 37
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.
Upvotes: 2