Указатель на член, который является ссылкой незаконным?
Скажем, у меня есть:
// This is all valid in C++11.
struct Foo {
int i = 42;
int& j = i;
};
// Let 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 &'
Я знаю, что это кажется бессмысленным, но мне просто интересно, почему это невозможно.
Почему это невозможно?
Ответы
Ответ 1
Указатель участника (в отличие от простого указателя на элемент) представляет собой просто смещение в структуре, а не указатель на всех. Вы можете получить данные через него только в сочетании с самой структурой (или указателем на структуру): значение смещения добавляется к адресу структуры, а результат разыменовывается для получения значения элемента.
Теперь предположим, что элемент является ссылкой, поэтому доступ к данным через него уже требует разыменования (компилятор скрывает его от нас, но ему нужно выплюнуть соответствующие инструкции в своем выводе). Если С++ должен был ссылаться на указатели-члены, они были бы еще одного типа: смещение, которое необходимо добавить к базе, а затем разыменовано дважды. Слишком много работы по улучшению уже неясной функции; запрет - это намного лучший выход.
Ответ 2
Стандарт С++ 11:
§8.3.3 p3 [dcl.mptr]
Указатель на член не должен указывать на статический член класса (9.4), члена с ссылочным типом или "cv void."
Кроме того, в общем случае:
§8.3.1 p4 [dcl.ptr]
[Примечание: нет указателей на ссылки; см. 8.3.2. [...] -end note]
§8.3.2 p5 [dcl.ref]
Не должно быть ссылок на ссылки, нет массивов ссылок и нет указателей на ссылки.
Ответ 3
Это невозможно, потому что вы не можете взять указатель на период отсчета.
Если вы можете взять указатель на ссылку, это будет несовместимо с поведением ссылок в стеке. Отношение С++ заключается в том, что ссылки не существуют. Таким образом, вы не можете сформировать указатель на них.
Например, &f::a
должен отличаться от &f::b
. И путем де-ссылки &f::b
вы эффективно достигаете указателя на ссылку, которая не допускается.
Ответ 4
Предоставление вам указателя на ссылку не дает вам никакой выразительной силы. С таким зверем вы ничего не можете сделать, что вам нелегко сделать со ссылкой или указателем. Все, что вы получаете от этого, добавило сложности.
И сделать указатель на член, который является ссылкой, не допускается для согласованности с правилом, которое запрещает указатели на ссылки, и потому что оно добавляет еще большую сложность. Дизайнеры языка, вероятно, решили, что небольшие выигрыши, которые вы получаете от них, не стоили того.
Это полностью мое мнение.