Let us say I have:
// This is all valid in C++11.
struct Foo {
int i = 42;
int& j = i;
};
// Let's take a pointer to the member "j".
auto b = &Foo::j; // Compiler is not happy here
// Note that if I tried to get a pointer to member "i", it would work, as expected.
Foo f;
std::cout << f.*b; // Try using the pointer to member
The compiler complains that I cannot take the address of the member because it is a reference. To be precise:
Semantic Issue: Cannot form a pointer-to-member to member 'j' of reference type 'int &'
I know doing this seems pointless, but I am only wondering why it cannot be done.
Why is this impossible?
Member pointer (as opposed to a simple pointer to a member) is simply an offset into the structure, not a pointer at all. You can get data through it only in conjunction with the structure itself (or a pointer to a structure): the value of the offset is added to the address of the structure, and the result is dereferenced to produce the value of the member.
Now suppose a member is a reference, so accessing data through it already requires a dereference (compiler hides it from us, but it needs to spit out the corresponding instructions in its output). If C++ were to allow member pointers to references, they'd be of yet another type: an offset that needs to be added to the base, and then dereferenced twice. It is too much work to improve an already obscure feature; prohibiting it is a much better way out.
C++11 standard:
§8.3.3 p3 [dcl.mptr]
A pointer to member shall not point to a static member of a class (9.4), a member with reference type, or “cv void.”
Also, in general:
§8.3.1 p4 [dcl.ptr]
[ Note: There are no pointers to references; see 8.3.2. [...] —end note ]§8.3.2 p5 [dcl.ref]
There shall be no references to references, no arrays of references, and no pointers to references.
It cannot be done because you cannot take a pointer to a reference- period.
If you could take a member pointer to a reference, this would be inconsistent with the behaviour of references on the stack. The attitude of C++ is that references do not exist. As such, you cannot form a pointer to them- ever.
For example, &f::a
would have to be different to &f::b
. And by de-referencing &f::b
, you would effectively be achieving a pointer to a reference, which is not allowed.
Allowing you to make a pointer to a reference does not give you any expressive power. There's nothing you can do with such a beast that you can't easily do with a reference or with a pointer. All you get out of it is added complexity.
And making a pointer to a member that is a reference is not allowed for consistency with the rule that forbids pointers to references, and because it adds even more complexity. The designers of the language probably decided that the little gains you get from these was not worth it.
This is totally just my opinion.
来源:https://stackoverflow.com/questions/8336274/pointer-to-member-that-is-a-reference-illegal