Consider the following C++ code:
class Func {
public:
void operator()() const { std::cout << this; }
};
int main() {
Func()(); // OK
std::cout << &Func(); // Can't take address of a temporary
}
In the body of operator()
, it is completely valid to treat this
as any other pointer. However, we're told time and again that we can't take the address of a temporary, yet that seems to me to be exactly what's happening. The first line of main
is perfectly fine, yet semantically, the line below it is identical. If I were to try to implement this in C to understand what's going on, I might dream up the following (C code):
typedef struct {} Func;
Func construct_Func() {
Func result;
return result;
}
void Func_operator_invoke(const Func* const this) {
printf("%p", this);
}
int main() {
Func_operator_invoke(&construct_Func()); // Can't take address of a temporary
}
Here, though, we run into a snag: we can't call our "simulated member function" on a temporary... which then begs the question -- why can we call member functions on temporaries in C++? If we can't take the address of a temporary, why can we pass the address of a temporary into a (member) function? Why is that any more valid than passing the address of a temporary into a free function?
Now, I fully expect that the answer to my question is "that's just how it is". That said, let me pose another question to preempt that answer: what does the standard say about calling member functions on temporary objects, and what is a reasonable way for a compiler to implement this? Could it simply push the temporary onto the stack, then pass the pointer to that memory to the function? If so, what's the reasoning behind the C and C++ standards not allowing similar behavior when taking the address of a temporary? As in, why doesn't the C code Func_operator_invoke(&(construct_Func()))
simply create an object, then pass a pointer to that object? Is there a published or well-known reason at all?