CPPLASTIC Telegram 377
Коли я тільки-но починав програмувати, то з величезним задоволенням писав на QBasic, а потім на Pascal. Згодом перейшов на 💻, яка вражала лаконічністю, та водночас мала в порівнянні певні незручності. Наприклад, ті ж нуль-терміновані рядки.

Але найбільше на початку дратувала робота з багатовимірними масивами. Якщо в тому ж паскалі можна дати змінній тип, наприклад, двовимірного масиву, щоб потім звертатися до його елементів як pixels[x,y], то в сішці таке не спрацює, і треба писати pixels[x][y].

Нічого страшного начебто — просто трохи інший запис. Але ця фішка перейшла і в 💻. А там доволі швидко зʼявляється бажання загорнути «сирі» масиви в якийсь клас з типобезпечнішою апішкою. Ну там матрицю ту ж зробити чи тензор якийсь, поперевантажувати оператори, щоб зручніше було, тощо.

Уявімо, що написали ви свій клас Matrix. Всередині у вас лежить якийсь масив; треба тепер визначити operator[], щоб можна було читати/писати конкретний елемент. Якби була багатовимірна індексація, то це суперлегко, причому дані всередині можна взагалі тримати в одновимірному масиві, а індекс обчислювати. Однак matrix[i][j] — це дві окремі операції, які можна записати як (matrix[i])[j]. Іншими словами, matrix[i] має повернути щось, на чому потім можна викликати .operator[](j).

Що це може бути? Ну, по-перше, можна повертати тупо вказівник на початок рядка, проте, я не почуваюся комфортно з цього приводу, бо забагато свободи: можна за межі піти, можна зберегти у змінну кудись, а потім навіть не дізнатися, що він інвалідувався (бо не володієш ним) тощо. При обережному використанні працюватиме, але наша мета ж знизити когнітивне навантаження, а не навпаки.

По-друге, можна повертати якийсь проксі-обʼєкт власного типу на кшталт Matrix::Row. Зробити, щоб створювати його могла тільки сама Matrix, по максимуму обмежити допустимі операції, перевизначити operator[]… Головняково якось, ще й сумнівно з погляду на швидкодію.

Натомість зазвичай перевантажують не індексацію, а операцію виклику функції operator(). Тоді є змога вказати довільну кількість параметрів. Але використання вже не настільки файне на вигляд, бо дужки круглі: matrix(i, j). Окрім неможливості в такому випадку зробити одночасно й індексацію, і виклик обʼєкта як функції (що все одно навряд чи комусь знадобиться), мені в цьому не подобається, що воно складніше сприймається. Око вже звикло, що квадратні дужки — доступ до елемента, круглі — виклик функції, тому натренований токенайзер у мозку даватиме хибні результати й сповільнюватиме читання й розуміння коду.

В інших, кращих мовах багатовимірна індексація вже присутня. Не тільки в спеціалізованих на кшталт 💻. Наприклад, у 💻 є, по-перше, багатовимірні масиви базових типів (int[,]), а по-друге, кастомний індексатор може приймати більше одного параметра: this[int row, int column]. (Так, мені дійсно подобається C# місцями). У Python 💻 метод __getitem__ завжди приймає тільки один параметр, проте, коли ви пишете matrix[i,j], то оці значення через кому запаковуються в кортеж, тобто викликається Matrix.__getitem__(matrix, (i, j)).

Щодо C++ же я давно змирився, що зручно тут не буває. І, уявіть собі, дарма!

Короч, починаючи з C++23 тепер є багатовимірна індексація, тобто це вже працює. Тепер operator[] може приймати довільну кількість параметрів різних типів:
m[0, 1, "shiii~"] = 42;

І до купи цей оператор тепер ще й статичним може бути.

Не вау яка фіча, і все ж мені до душі.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🤯5🔥2



tgoop.com/cpplastic/377
Create:
Last Update:

Коли я тільки-но починав програмувати, то з величезним задоволенням писав на QBasic, а потім на Pascal. Згодом перейшов на 💻, яка вражала лаконічністю, та водночас мала в порівнянні певні незручності. Наприклад, ті ж нуль-терміновані рядки.

Але найбільше на початку дратувала робота з багатовимірними масивами. Якщо в тому ж паскалі можна дати змінній тип, наприклад, двовимірного масиву, щоб потім звертатися до його елементів як pixels[x,y], то в сішці таке не спрацює, і треба писати pixels[x][y].

Нічого страшного начебто — просто трохи інший запис. Але ця фішка перейшла і в 💻. А там доволі швидко зʼявляється бажання загорнути «сирі» масиви в якийсь клас з типобезпечнішою апішкою. Ну там матрицю ту ж зробити чи тензор якийсь, поперевантажувати оператори, щоб зручніше було, тощо.

Уявімо, що написали ви свій клас Matrix. Всередині у вас лежить якийсь масив; треба тепер визначити operator[], щоб можна було читати/писати конкретний елемент. Якби була багатовимірна індексація, то це суперлегко, причому дані всередині можна взагалі тримати в одновимірному масиві, а індекс обчислювати. Однак matrix[i][j] — це дві окремі операції, які можна записати як (matrix[i])[j]. Іншими словами, matrix[i] має повернути щось, на чому потім можна викликати .operator[](j).

Що це може бути? Ну, по-перше, можна повертати тупо вказівник на початок рядка, проте, я не почуваюся комфортно з цього приводу, бо забагато свободи: можна за межі піти, можна зберегти у змінну кудись, а потім навіть не дізнатися, що він інвалідувався (бо не володієш ним) тощо. При обережному використанні працюватиме, але наша мета ж знизити когнітивне навантаження, а не навпаки.

По-друге, можна повертати якийсь проксі-обʼєкт власного типу на кшталт Matrix::Row. Зробити, щоб створювати його могла тільки сама Matrix, по максимуму обмежити допустимі операції, перевизначити operator[]… Головняково якось, ще й сумнівно з погляду на швидкодію.

Натомість зазвичай перевантажують не індексацію, а операцію виклику функції operator(). Тоді є змога вказати довільну кількість параметрів. Але використання вже не настільки файне на вигляд, бо дужки круглі: matrix(i, j). Окрім неможливості в такому випадку зробити одночасно й індексацію, і виклик обʼєкта як функції (що все одно навряд чи комусь знадобиться), мені в цьому не подобається, що воно складніше сприймається. Око вже звикло, що квадратні дужки — доступ до елемента, круглі — виклик функції, тому натренований токенайзер у мозку даватиме хибні результати й сповільнюватиме читання й розуміння коду.

В інших, кращих мовах багатовимірна індексація вже присутня. Не тільки в спеціалізованих на кшталт 💻. Наприклад, у 💻 є, по-перше, багатовимірні масиви базових типів (int[,]), а по-друге, кастомний індексатор може приймати більше одного параметра: this[int row, int column]. (Так, мені дійсно подобається C# місцями). У Python 💻 метод __getitem__ завжди приймає тільки один параметр, проте, коли ви пишете matrix[i,j], то оці значення через кому запаковуються в кортеж, тобто викликається Matrix.__getitem__(matrix, (i, j)).

Щодо C++ же я давно змирився, що зручно тут не буває. І, уявіть собі, дарма!

Короч, починаючи з C++23 тепер є багатовимірна індексація, тобто це вже працює. Тепер operator[] може приймати довільну кількість параметрів різних типів:

m[0, 1, "shiii~"] = 42;

І до купи цей оператор тепер ще й статичним може бути.

Не вау яка фіча, і все ж мені до душі.

BY Cіпласпластик


Share with your friend now:
tgoop.com/cpplastic/377

View MORE
Open in Telegram


Telegram News

Date: |

ZDNET RECOMMENDS Those being doxxed include outgoing Chief Executive Carrie Lam Cheng Yuet-ngor, Chung and police assistant commissioner Joe Chan Tung, who heads police's cyber security and technology crime bureau. As of Thursday, the SUCK Channel had 34,146 subscribers, with only one message dated August 28, 2020. It was an announcement stating that police had removed all posts on the channel because its content “contravenes the laws of Hong Kong.” Activate up to 20 bots Polls
from us


Telegram Cіпласпластик
FROM American