Почему возврат указателя вместо самой переменной является правильным для функций со ссылочным типом возврата - PullRequest
0 голосов
/ 07 июля 2019

Рассмотрим следующий пример класса, взятый из Бьярн Страуструп - Обзор C ++ (2-е издание) :

class Vector {
public:
    Vector(int s) :elem{new double[s]}, sz{s} { }
    double& operator[](int i) { return elem[i]; }
    int size() { return sz; }
private:
    double* elem;
    int sz = 0;
};

Насколько я понимаю, в double& operator[] теле метода, elem[i] (что совпадает с elem + i) имеет тип указателя на удвоение double*.

Итак, вопрос в том, почему правильно возвращать указатель на удвоение хотя сигнатура метода подразумевает ссылку на двойную (саму переменную) для возврата?

Кроме того, компилятор выдает ошибку, если я попытался вернуть разыменованную *elem[i] вместо elem[i].

1 Ответ

1 голос
/ 10 июля 2019

Per [expr.sub] / 1 :

Выражение postfix, за которым следует выражение в квадратных скобках, является выражением postfix.Одно из выражений должно быть glvalue типа «array of T» или prvalue типа «pointer to T», а другое должно быть prvalue перечисления с незаданной областью или целочисленного типа.Результат имеет тип «T».Тип «T» должен быть полностью определенным типом объекта. Выражение E1[E2] идентично (по определению) *((E1)+(E2)), , за исключением того, что в случае операнда массива результатом является lvalue, если этот операнд является lvalue, а xvalue в противном случае.Выражение E1 упорядочено перед выражением E2.

Здесь elem имеет тип double*, а i имеет тип int.elem[i] по определению эквивалентно *(elem + i), который является lvalue типа double.*elem[i] пытается разыменовать a double, который плохо сформирован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...