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

时间:2011-12-01 03:41:04

标签: c++ language-lawyer pointer-to-member

我们说我有:

// 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;'

我知道这样做似乎毫无意义,但我只是想知道为什么不能这样做。

为什么这不可能?

4 个答案:

答案 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)

允许您制作指向引用的指针并不会给您任何表现力。你无法用引用或用指针轻易做到这样的野兽。所有你摆脱它都增加了复杂性。

不允许指向作为引用的成员的指针与禁止引用指针的规则保持一致,并且因为它增加了更多的复杂性。该语言的设计者可能认为你从中得到的微不足道的收益并不值得。

这完全是我的意见。