fro*_*cqc 19 c++ pointer-to-member language-lawyer
我们说我有:
// 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
Run Code Online (Sandbox Code Playgroud)
编译器抱怨我不能获取成员的地址,因为它是一个引用.确切地说:
语义问题:无法形成指向成员的指针指向成员'j'的引用类型'int&'
我知道这样做似乎毫无意义,但我只是想知道为什么不能这样做.
为什么这不可能?
Xeo*_*Xeo 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]
不应引用引用,不引用引用数组,也不引用引用指针.
Pup*_*ppy 11
它无法完成,因为您无法获取指向引用期的指针.
如果您可以将成员指针指向引用,则这将与堆栈上的引用行为不一致.C++的态度是引用不存在.因此,您无法形成指向它们的指针.
例如,&f::a必须与之不同&f::b.通过取消引用&f::b,您将有效地实现指向引用的指针,这是不允许的.
成员指针(与指向成员的简单指针相对)只是结构的偏移量,而不是指针.您只能结合结构本身(或指向结构的指针)获取数据:将偏移量的值添加到结构的地址,并取消引用结果以生成成员的值.
现在假设一个成员是一个引用,所以通过它访问数据已经需要一个解除引用(编译器将它隐藏起来,但它需要在其输出中吐出相应的指令).如果C++允许成员指向引用,它们将是另一种类型:需要添加到基础的偏移量,然后解除引用两次.改进已经模糊不清的功能是太多的工作; 禁止它是一个更好的出路.