With the above set-up it is quite likely that the compiler elides the copy constructor and, instead, directly constructs the temporary temp
in the location where the return value will be expected. Copy elision is explicitly allowed even if the copy constructor has side effects. However, even if the copy is elided, the copy or move constructor still has to be accessible, i.e., the potential of copy elision doesn't relax the rules on the corresponding constructor to be accessible.
If you feel you absolutely want to have a copy constructor called, you can force copy construction, e.g., by passing the result through an identity function:
template <typename T>
T const& identity(T const& object) {
return object;
}
// ...
return identity(temp);
Normally, you'd want the copy constructor to be elided, however.