指向非法参考成员的指针?

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]
不应引用引用,不引用引用数组,也不引用引用指针.

  • @fronsacqc:因为指针指向对象,但引用不是对象. (3认同)

Pup*_*ppy 11

它无法完成,因为您无法获取指向引用期的指针.

如果您可以将成员指针指向引用,则这将与堆栈上的引用行为不一致.C++的态度是引用不存在.因此,您无法形成指向它们的指针.

例如,&f::a必须与之不同&f::b.通过取消引用&f::b,您将有效地实现指向引用的指针,这是不允许的.

  • @MarkRansom:你可以取*引用的*地址,它是引用对象的地址.你不能指向一个引用本身. (2认同)

das*_*ght 6

成员指针(与指向成员的简单指针相对)只是结构的偏移量,而不是指针.您只能结合结构本身(或指向结构的指针)获取数据:将偏移量的值添加到结构的地址,并取消引用结果以生成成员的值.

现在假设一个成员是一个引用,所以通过它访问数据已经需要一个解除引用(编译器将它隐藏起来,但它需要在其输出中吐出相应的指令).如果C++允许成员指向引用,它们将是另一种类型:需要添加到基础的偏移量,然后解除引用两次.改进已经模糊不清的功能是太多的工作; 禁止它是一个更好的出路.

  • @fronsacqc当然,如果你把它变成一些有意义的语义,这个功能就可以工作了.不幸的是,对于这样一个不起眼的功能这样做属于问题领域,而不是解决方案.幸运的是,标准化委员会的某个人早就认识到这一点,并在该功能成为问题之前将其禁用. (2认同)