The buffer
pointer is an "lvalue", but when the cast operation is applied to it, the expression:
(char*) buffer
is an "rvalue" (actually a "modifiable rvalue" - but I think that only matters in the upcoming C++0x). Non-const references cannot be bound to rvalues.
However, const references can be bound to rvalues. So the following modification to your program will compile:
void foo(char* const& p) // added 'const'
Stephan T. Lavavej recently posted a blog entry that has great information about lvalues, rvalues, and references:
The article is actually about the new "rvalue references" that are coming in C++0x, but it has a great explanation of what lvalues and rvalues are and how they can and cannot work with references in C++98. It's a long read, but very much well worth it.