我们说我有:
// 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
编译器抱怨我无法获取成员的地址,因为它是一个引用。确切地说:
语义问题:无法形成指向成员的指针指向成员'j'的引用类型'int&amp;'
我知道这样做似乎毫无意义,但我只是想知道为什么不能这样做。
为什么这不可能?
答案 0 :(得分:12)
C ++ 11标准:
§8.3.3p3[dcl.mptr]
指向成员的指针不得指向类的静态成员(9.4),具有引用类型的成员或“cv void”。
另外,一般来说:
§8.3.1p4[dcl.ptr]
[注意:没有指向引用的指针;见8.3.2。 [...] - 注意事项]§8.3.2p5[dcl.ref]
不得引用引用,没有引用数组,没有引用指针。
答案 1 :(得分:11)
无法完成,因为您无法指向参考期间。
如果您可以将成员指针指向引用,则这将与堆栈上的引用行为不一致。 C ++的态度是引用不存在。因此,你无法形成指向它们的指针。
例如,&f::a
必须与&f::b
不同。通过取消引用&f::b
,您将有效地实现指向引用的指针,这是不允许的。
答案 2 :(得分:6)
成员指针(与指向成员的简单指针相对)只是结构的偏移量,而不是指针。您只能结合结构本身(或指向结构的指针)来获取数据:将偏移量的值添加到结构的地址中,并取消引用结果以生成成员的值。 / p>
现在假设一个成员是一个引用,所以通过它访问数据已经需要取消引用(编译器将它隐藏起来,但它需要在其输出中吐出相应的指令)。如果C ++允许成员指向引用,它们将是另一种类型:需要添加到基础的偏移量,然后解除引用两次。改进已经模糊不清的功能是太多的工作;禁止它是一个更好的出路。
答案 3 :(得分:1)
允许您制作指向引用的指针并不会给您任何表现力。你无法用引用或用指针轻易做到这样的野兽。所有你摆脱它都增加了复杂性。
不允许指向作为引用的成员的指针与禁止引用指针的规则保持一致,并且因为它增加了更多的复杂性。该语言的设计者可能认为你从中得到的微不足道的收益并不值得。
这完全是我的意见。