In the below example I want to find out why the copy constructor isn't called when I return an automatic variable from the doit() function. I understand that the first version of handler is called because we have a temporary object but can't figure out why the copy constructor isn't called while creating that temporary object (copies everything from s to a temporary object).
#include <iostream>
using namespace std;
class S{
public:
S(){std::cout<<"Constructor\n";}
S(const S& s){std::cout<<"Copy Constructor\n";}
~S(){std::cout<<"Destructor\n";}
};
S doit(){
S s;
return s;
}
void handler(S&& r){
std::cout<<"Here\n";
}
void handler(const S& r){
std::cout<<"Here2\n";
}
int main() {
handler(doit());
}
Actually, there is a constructor being called in your code according to the rules of the language. However, the compiler has optimized that out and so you don't see the call. If you compile with -fno-elide-constructors
you should see the copy-constructor being invoked.
Note that the copy-constructor will only be invoked because the defaulted move-constructor is suppressed. If you add that back like this:
S(S&&) = default;
then this move-constructor will be called instead. Here's a demo.