Указатель на участника, который является незаконной ссылкой? - PullRequest
19 голосов
/ 01 декабря 2011

Допустим, у меня есть:

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

Я знаю, что это кажетсябессмысленно, но мне только интересно, почему это невозможно сделать.

Почему это невозможно?

Ответы [ 4 ]

12 голосов
/ 01 декабря 2011

C ++ 11 стандарт:

§8.3.3 p3 [dcl.mptr]
Указатель на член не должен указывать на статический член класса (9.4), элемент со ссылочным типом или «cv void».

Кроме того, в целом:

§8.3.1 p4 [dcl.ptr]
[Примечание: нет указателей на ссылки;см. 8.3.2.[...] - конец примечания]

§8.3.2 p5 [dcl.ref]
Не должно быть ссылок на ссылки, массивов ссылок и без указателей на ссылки .

11 голосов
/ 01 декабря 2011

Это невозможно сделать, потому что вы не можете взять указатель на ссылочный период.

Если бы вы могли взять указатель члена на ссылку, это было бы несовместимо с поведением ссылок в стеке.Отношение C ++ заключается в том, что ссылки не существуют.Таким образом, вы не можете сформировать указатель на них.

Например, &f::a должен отличаться от &f::b.И, сняв ссылку на &f::b, вы фактически получите указатель на ссылку, что недопустимо.

6 голосов
/ 01 декабря 2011

Указатель элемента (в отличие от простого указателя на элемент) - это просто смещение в структуре, а не указатель вообще.Через него можно получить данные только в сочетании с самой структурой (или указателем на структуру): значение смещения добавляется к адресу структуры, а результат разыменовывается для получения значения элемента.

Теперь предположим, что элемент является ссылкой, поэтому доступ к данным через него уже требует разыменования (компилятор скрывает их от нас, но ему нужно выкладывать соответствующие инструкции в свои выходные данные).Если бы C ++ позволял указателям на ссылки на элементы указывать, они были бы другого типа: смещение, которое необходимо добавить к базе, а затем дважды разыменовать.Это слишком много работы, чтобы улучшить и без того неясную функцию;Запретить это гораздо лучший выход.

1 голос
/ 01 декабря 2011

Разрешение на указатель на ссылку не дает вам никакой выразительной силы.Вы ничего не можете сделать с таким зверем, которого вы не можете легко сделать с помощью ссылки или указателя.Все, что вы получаете от этого - это дополнительная сложность.

И создание указателя на элемент, являющийся ссылкой, не допускается для согласованности с правилом, которое запрещает указатели на ссылки, и потому что это добавляет еще большую сложность.Разработчики языка, вероятно, решили, что небольшие выгоды, которые вы получите, не стоили этого.

Это полностью мое мнение.

...