21

假设我有:

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

编译器抱怨我不能获取成员的地址,因为它是一个引用。准确地说:

语义问题:无法形成指向成员的指针,指向引用类型为“int &”的成员“j”

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

为什么这是不可能的?

4

4 回答 4

13

无法做到这一点,因为您无法获取指向参考期的指针。

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

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

于 2011-12-01T04:02:28.020 回答
13

C++11 标准:

§8.3.3 p3 [dcl.mptr]
指向成员的指针不应指向类 (9.4) 的静态成员、具有引用类型的成员或“cv void”。</p>

另外,一般来说:

§8.3.1 p4 [dcl.ptr]
[注意:没有指向引用的指针;见 8.3.2。[...]——结束注]

§8.3.2 p5 [dcl.ref]
不得有对引用的引用,没有引用数组,也没有指向引用的指针。

于 2011-12-01T04:04:05.993 回答
7

成员指针(与指向成员的简单指针相反)只是结构的偏移量,根本不是指针。您只能通过它与结构本身(或指向结构的指针)一起获取数据:将偏移量的值添加到结构的地址,并将结果取消引用以产生成员的值。

现在假设一个成员是一个引用,因此通过它访问数据已经需要一个解引用(编译器对我们隐藏它,但它需要在其输出中吐出相应的指令)。如果 C++ 允许成员指针指向引用,它们将是另一种类型:需要添加到基数的偏移量,然后取消引用两次。改进一个已经晦涩难懂的功能需要做太多的工作;禁止它是一个更好的出路。

于 2011-12-01T04:18:16.880 回答
1

允许您创建指向引用的指针并不会赋予您任何表达能力。对于这样一个使用引用或指针无法轻松完成的野兽,您无能为力。您从中得到的只是增加了复杂性。

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

这完全只是我的意见。

于 2011-12-01T05:05:13.863 回答