Don't confuse language concepts and implementation details. The fact that it is a pointer "under the hood" is, as you say, an implementation detail, but it is not a pointer being passed by value as far as the language is concerned; it is passed by reference.
Actually, my bringing in of implementation details was to cement that references may in fact be pointers--for the sake of showing that my argument holds in actual architectural-level practice.
As far as your distinction, I think (in this case) it's a distinction without a difference. I will agree that references and pointers have a few semantic differences (for example, you can do arithmetic on pointers, and (so) references can do more checking), but really there's no difference between them. They act the same way, and you can use one instead of the other with almost equal facility.
For purposes of this discussion, the key point is that passing references into functions works in the same way as passing pointers. In the above example, the answer is "the reference int&example is passed by value, since its value is copied"--nevermind that that copying might be optimized away, just as inlining might similarly be able to optimize away other copies for pointers. Semantically thinking of the reference being copied doesn't break anything, and is actually closer to truth in practice.
If you bring implementation details and "under the hood" into the picture, then nothing exists in any language, because it all boils down to machine code being executed in one way or another, and machine code typically has no templates, no structures, no functions, no scope, no name spaces, no closures, no typing... nothing. A language just abstract such things so that the programmer can write code what the program is supposed to do, and the compiler/virtual machine/whatever ensures that the program is actually doing just that on the particular computer running it.
Reducto ad absurdum, but still somewhat relevant. Machine code has comparably few features, I'll agree, but in this case, the idea of "pointer"s actually exists, albeit not with static checks.
And I completely agree that whether "references" are implemented at the machine level through pointers or at the compiler level through optimizations, the point is that they exist in C++, which abstracts it. However, the converse of that was never my point; as above, I brought in implementation details to show how it works in practice. I had intended the first main paragraph of my last post to address that.
The point with all this is that the (key) properties of "references" exactly mirror those of pointers: they are datatypes held in variables, and they get copied by value when they are passed into functions, just as much as pointers. That's the functionality that C++ exposes and abstracts for us. C++ programmers might not think about it that way, since in the ideal case, they can be optimized just like any other code. But as we've agreed, that last is an implementation detail.
Edited by Geometrian, 08 January 2013 - 06:37 PM.