指向非法引用的成员的指针

Pointer to member that is a reference illegal?

本文关键字:成员 指针 引用 非法      更新时间:2023-10-16

假设我有:

// 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'的成员指针

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

为什么不可能?

不能这样做,因为不能使用指向引用周期的指针。

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

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

c++ 11标准:

§8.3.3 p3 [dcl. 3]mptr]
指向成员的指针不能指向类(9.4)的静态成员、、引用类型的成员或" cv void "。

通常:

§8.3.1 p4 [dcl.ptr]
[注:没有指向引用的指针;看到8.3.2。[…

§8.3.2 p5 [dcl. c]ref)
不能有引用的引用,不能有引用的数组,不能有指向引用的指针

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

现在假设成员是一个引用,那么通过它访问数据已经需要解引用(编译器对我们隐藏了它,但它需要在输出中给出相应的指令)。如果c++允许成员指针指向引用,那么它们将是另一种类型:需要添加到基类的偏移量,然后解引用两次。要改进一个已经很模糊的功能,工作量太大了;禁止它是更好的解决办法。

允许创建指向引用的指针并不会赋予您任何表达能力。对于这样一个巨兽,没有什么是你不能用引用或指针轻松做到的。你从中得到的只是增加了复杂性。

创建指向引用成员的指针是不允许的,这与禁止指向引用的指针的规则是一致的,因为它增加了更多的复杂性。这门语言的设计者可能认为,你从中获得的一点好处是不值得的。

这完全是我的个人意见。