Как стать автором
Обновить

Комментарии 28

А в Паскале многомерные массивы были 50+ лет назад. Да и модули Турбо Паскаля вменяемее и существуют лет 30...

В Си многомерные массивы были 40+ лет назад. Но тут речь идёт о пользовательских перегрузках операторов. В Паскале нет возможности, чтобы Screen[x,y] := RGB(1,2,0); ставил точку на экране по указанным координатам.

Насколько я помню, даже в относительно развивающемся FreePascal до сих пор в принципе невозможно определить оператор [] для объекта произвольного типа. С точки зрения Паскаля [] - это вообще не оператор.

В дельфи есть хорошая замена через индексируемые свойства


property ByIndex[i: integer]: TField read GetFieldByIndex write SetFieldByIndex;
property ByXY[X: integer; Y: integer]: TRGB read GetByXY write SetByXY;

Получается, насчёт примера со Screen двумя сообщениями выше я был не прав.
Можно обращаться к объекту Screen:


Screen.ByXY[1,2] := RGB(1,2,3);

а если описать как


property ByXY[X: integer; Y: integer]: TRGB read GetByXY write SetByXY; default;

то и просто


Screen[1,2] := RGB(1,2,3);

Вообще, с терминологией могут быть проблемы. Я лично придерживаюсь того, что операторы -- это if, while и т.п., ну а плюсы-минусы -- это операции. Соответственно, присваивание в Паскале -- оператор, а в Си -- операция. Ну а что возможности переопределения в Дельфях/ФриПаскале сильно ограничены -- тут да; развитие языка, как по мне, пошло по абсолютно неверному пути (стали подражать Жабе, похоже, -- а она ущербна по определению, ибо "управляемый" язык для работы на виртмашине, а не относительно низкоуровневый для работе на голом железе, как и классический Паскаль, и Си).

Проблема русского языка. На английском это statements и operators.

Проблема перевода. Назвали бы по-нормальному — инструкция (statement) и оператор (operator) — и никакой путаницы.

О терминах не спорят, о терминах договариваются.

Массивы массивов были, многомерные массивы -- нет. Ну а что в Паскале много чего нет -- оно понятно. Идеального языка вообще нет (и быть не может, по большому счёту, ибо требования противоречивы).

Массивы массивов были, многомерные массивы — нет

Но ведь на практике вообще нет никакой разницы, кроме синтаксиса A[x][y] вместо A[x,y].

Ну, более громоздкий и менее читаемый синтаксис тоже не есть хорошо. Да и с переопределением операций проблемы.

Где так там громоздкость? Принято ставить пробел после запятой, и вот A[x][y] и A[x, y] уже равны. Это сделано не из-за громоздкости, а ради перегрузки оператора.

Нет, всё же оператор двойного индекса это синтаксический сахар.
Потому что без проблем для опеределения пользовательской операции A[x][y] можно перегрузить A[x], чтобы возвращал std::pair<A&&, decltype(x)> и к этому классу (необязательно std::pair, можно написать свой, чтобы не путался с STL) сделать перегруженный operator[], где уже будет доступно 2 параметра x и y. Из-за форвардинга A&& на этом нет никакого оверхеда, в сравнении с прямой перегрузкой оператора [] с двумя индексами.

Многомерный индексатор конечно был ожидаемой фичей.

Вы не можете просто взять и написать arr[0, 1, 2]

Вообще-то могу, посредством перегрузки оператора запятой для упаковки индексов в тапл. Костыль конечно, но до 17-го стандарта работает, в 20-м задепрекейчен ради этой самой фичи в 23-м.

overload the subscript operator with a brace-enclosed list (so you could say c[{1,2,3}])

Перегрузить оператор индексирования со списком, заключенным в фигурные скобки (чтобы вы могли написать с[{1,2,3}]).

Вы кажется текст на англ забыли удалить

А в C++ планируется что-то типа шарповых Property? Чтобы за одним именем скрывался и и метод чтения и метод записи?

Я пытался найти какой-то устоявшийся паттерн для работы с полями класса в C++, но как-то ничего не нашёл лучше пары методов getSmth() / setSmth(). Может кто подскажет, как в современных плюсах правильно и канонично такое реализовывать?

Костыльно-с. Как, впрочем, половина в Це++. Постоянно удивляюсь: добавить что-то навороченное комитет по стандартизации может, а простое и очевидное... религия, что ли, не позволяет?..

property это сахар

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

Ну дык и Си -- тоже сахар. И ассемблер тоже. Что мешало писать прямо в машинном коде?

Всё правильно: у нас же есть форточка, можно лазить через неё, а дверь это сахар. Много лет жили без двери и ещё столько же проживём.

Дверь это не сахар, потому что у неё, по сравнению с форточкой, лучше объективные измеримые характеристики: пропускная способность в человеках в час и энергозатраты на один проход.

Тогда property -- тоже не сахар, потому что написать код с его помощью быстрее, проще, понятнее и безошибочнее, чем костылями.

Свойства — это прежде всего инструмент. В языках типа c# (и в java через костыли get/set) взамодействие с объектами через свойства очень часто является обязательным требованием у фреймворков сериализации (DataContractSerializer), ORM (NHibernate) или биндинга на GUI (WPF). Потому что рантайм может разными способами перехватывать вызовы методов и таким образом реагировать на изменение свойств. В C++ нет динамического рантайма, нет JIT-компиляции, нет рефлексии, поэтому свойства там не будут утилитарные, а останется чисто синтаксический сахарок.

первые две "практичные" фичи очень редко нужны

а вот работа со строками так до конца не доделана, qstring уже в версии 3 всё это умеел

господи, сколько ж лет им долбиться надо было чтобы добавить contains в стандарт. Правда остальной api стандартной либы все так и остается дерьмом

T& operator[](size_t const r, size_t const c) noexcept
{
   return data_[r * C + c];
}
T const & operator[](size_t const r, size_t const c) const noexcept
{
   return data_[r * C + c];
}

А можете расшифровать эту магию.
Что здесь означает T& и T const & и зачем нужны они оба, а не только один из них?

Ключевое отличие справа от аргументов функции (const noexcept)
Второй метод нужен, чтобы вызываеть его на const-объекте и "гарантировать" его дальнейшую неизменность, отдавая наружу не просто T&, а const T&

Зарегистрируйтесь на Хабре, чтобы оставить комментарий