Здравствуйте, INTP_mihoshi, Вы писали:
INT>Здравствуйте, SWW, Вы писали:
SWW>>С одной стороны, математическая нотация не так уж однозначна: достаточно сказать, что в одних странах в качестве десятичного разделителя используется точка, в других — запятая. Если в таком простом вопросе нет единства, что уж говорить о более сложных вещах.
INT>ИМХО любая текстовая или графическая нотация либо неоднозначна, либо громоздка. Но в математике есть точная семантическая нотация, т.е. совокупность однозначно интерпретируемых понятий. Например, поле, или там, целое число — имеют однозначный смысл. А вот в программировании такие, скажем, базовые понятия, как класс и функция понимаются в каждом языке по разному.
Дело не только и не столько в семантике — хотя это тоже проблема.
Но, что за смысл Вы вкладываете в понятие "текстовая или графическая нотация" — ИМХО, любая нотация либо то, либо другое
И мне видется очень важным, что бы ко всему прочему, "программисткой нотацией" можно было с легкость пользоваться вооружившись "карандашом и листком бумаги".
Но опять же... повторюсь... в этом вопросе мы напоминаем мне филогов с их определением ямба и хрея С их точки зрения, наверное, оно тоже "достаточно формализованно"... покрайней мере моя жена так и не поняла почему я долго над этим определением смеялся... Рискну процетировать (не пинать за оффтоп, пожалуйста, ИМХО, оно весьма поучительно).
Упрощённо это выглядит так:
Ямб — это когда ударение на четных слогах. Но может быть и на нечетных.
Хорей — это когда ударение на нечетных слогах. Но может быть и на четных.
Ничего не напоминает?
Тем не менее, они (филологи) с легкостью различают ямб и хорей... вот только объяснить другим, для большинства из них проблема... Т.к. четкое определение данное (кем бы вы думали...) — Колмогоровым (угу, тем самым) — воспринимается ими с трудом, и расценивается как усложнение.
Так и мы — вполне можем понимать друг друга... невзирая даже на отсутсвие четкой терминологии... но вот "объяснить другим"... и смотрим на введение формализации, как на излишнее усложнение
---
С уважением, Сиваков Константин.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Kh_Oleg, Вы писали:
K_O>>Не надо впадать в крайности. "+" — это символ сложения. В повседеневной жизни мы обычно складываем числа. K_O>>А вот "++" — это операция инкремента. Еще нужно объяснять, что это за операция такая, и что для чисел она означает увеличение на единицу. Ну а перегрузка операторов — это вообще из серии "некоторое действие, которое выглядит как сложение, но делает то, что знаю только я!" WH>Ну если тебе так хочется то ты можешь продолжать писать на языках которые ни чего не умеют, а я буду использовать язык который позволяет мне выражать свои мысли так как я хочу. WH>Например на С++ можно написать шаблон такого массива что... короче пример WH>
WH>те не будет создано ни одного временного массива. WH>подробности в книге "Шаблоны С++. Стравочник разработчика" Вандевурд и Джосаттис
Два замечания:
Во-первых, в выражении использованы значения всех переменных, кроме массива f. Причем использованы без инициализации. Понятно, что в реальном проекте ты уж наверняка все бы проинициализировал. Только это как-то... неаккуратненько. А потом на форуме и всплывают вопросы, а почему это у меня в Debug все работает, а в Release — нет.
Второе, в твоем "кратком" выражении, за которое ты ратуешь, ни фига не понятно, где переменная типа double, а где — элемент массива. Упаси Бог, когда-нибудь отлаживать ошибку в таком выражении. Зачем нужна такая краткость в ущерб читабельности?
Но и это не главное.
Цитирую сам себя:
некоторое действие, которое выглядит как сложение, но делает то, что знаю только я!
Не зная, как перегружены операторы для этих массивов абсолютно невозможно сказать, какой элемент массива учавствует в выражении!!!
WH>Тоже со строками WH>
Оператор сложения для строк, означающий конкатенацию — это, пожалуй, единственное применение перегрузки операторов, где оно действительно необходимо. А все потому, что в ЯП строка должна быть базовым типом! Таким как char, int, double. Так и string.
Вот для базовых (примитивных) типов операторы должны быть определены. Но не для составных типов, определяемых программистом!
WH>Тоже с векторами и матрицами WH>
Умножение матриц — это целый алгоритм, к тому же, перемножение матриц, операция некоммутативная (A*B != B*A), а из текста этого не видно. Понятно, что часто хочется записать выражение в программе в виде, близком к виду формулы из книги. Но тогда, для того, чтобы понять, что здесь происходит надо будет эту самую книгу перечитать.
WH>Так на каком языке лучше писать? на том где есть шаблоны и перегрузка операторов или на том где их нет?
На том, на котором можно более кратно, точно и понятно выразить свою мысль. В этих примерах было кратко, не совсем точно (неинициализированные переменные) и непонятно.
WH>ЗЫ Судя по тому что ты говоришь для тебя лучший язык это ассемблер. Простой, понятный, нет неоднозначностей. Просто чудо, а не язык...
Точно, одна беда — слишком уж он низкоуровневый
WH>ЗЗЫ А тех кто перегружает операторы не интуетивным образом надо сжигать на костре и предавать анафиме...
Но почему язык позволяет таким индивидуумам так хулиганить?
Здравствуйте, Kh_Oleg, Вы писали:
K_O>Два замечания: K_O>Во-первых, в выражении использованы значения всех переменных, кроме массива f. Причем использованы без инициализации.
1)Во всех трех примерах написано //тут инициализация. Тебе что больше не кчему предратся?
2)Если ты посмотришь внимательно то значение массива f тоже использовано. Оператор *= K_O>Понятно, что в реальном проекте ты уж наверняка все бы проинициализировал. Только это как-то... неаккуратненько.
А нахрена в примерах писать гору не относящегося к делу кода? K_O>Второе, в твоем "кратком" выражении, за которое ты ратуешь, ни фига не понятно, где переменная типа double, а где — элемент массива. Упаси Бог, когда-нибудь отлаживать ошибку в таком выражении. Зачем нужна такая краткость в ущерб читабельности?
А что должно быть понятно в выражении которое писано от балды? В реальной программе будут вполне себе говорящие имена.
K_O>Не зная, как перегружены операторы для этих массивов абсолютно невозможно сказать, какой элемент массива учавствует в выражении!!!
Один раз читаем доку в которой написано что-то типа
Для типа array_t перегружены все арифметические операторы так что запись вида arr1*arr2 трактуется как поэлементное умножение массивов. А запись вида const*arr трактуется как поэлементное умножение массива на константу.
Я знаю что из меня плохой писатель хелпов. Но скажи что тебе после прочтения этого будет не понятно в выражении тапа
arr1=arr2*const1-arr3/const2;
Ы? K_O>Оператор сложения для строк, означающий конкатенацию — это, пожалуй, единственное применение перегрузки операторов, где оно действительно необходимо. А все потому, что в ЯП строка должна быть базовым типом! Таким как char, int, double. Так и string.
На сччет того должны быть строки одним из базовых типов языка или нет это тема для отдельного флейма. K_O>Вот для базовых (примитивных) типов операторы должны быть определены. Но не для составных типов, определяемых программистом!
Категорически не согласен. Допустим я реализовал библиотеку для работы с числами в несколько сотен быйт и что мне теперь для них нельзя операторы перегрузить?
А взят тотже boost::spirit когда надо быстро написать не сложный парсер то эта штука очень удобна. Но он небыл бы возможен без перегрузки операторов.
K_O>Умножение матриц — это целый алгоритм, к тому же, перемножение матриц, операция некоммутативная (A*B != B*A), а из текста этого не видно. Понятно, что часто хочется записать выражение в программе в виде, близком к виду формулы из книги. Но тогда, для того, чтобы понять, что здесь происходит надо будет эту самую книгу перечитать.
Я вобще не понимаю как можно писать программу для предметной области хотябы поверхностно не разобравшись в ней? И вобще С++ это Язык ВЫСОКОГО Уровня, а ЯВУ были созданы для того чтобы сложные действия можно было записать просто.
K_O>На том, на котором можно более кратно, точно и понятно выразить свою мысль.
Это на каком если не секрет? K_O>В этих примерах было кратко, K_O>не совсем точно (неинициализированные переменные)
Это не аргумент. см выше. K_O>и непонятно.
Такой чувство что ты на принци пошол. Что тут не понятного?
K_O> Но почему язык позволяет таким индивидуумам так хулиганить?
А тут либо полный запрет на перегрузку и тогда нельзя писать интуитивно понятные бибииотеки. Либо есть шанс что один придурок из тысячи перегрузит операторы так что можно будет складывать метры с килограммами. Но так-как таких орлов практически нет то я предпочитаю чтобы была возможность перегружать операторы.
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
WH>А тут либо полный запрет на перегрузку и тогда нельзя писать интуитивно понятные бибииотеки. Либо есть шанс что один придурок из тысячи перегрузит операторы так что можно будет складывать метры с килограммами. Но так-как таких орлов практически нет то я предпочитаю чтобы была возможность перегружать операторы.
Перегрузка не всегда понятна и очевидна. Кроме того при поиске кода в исходниках по функции легче найти ее исходный код.
и чем Equals хуже == ????? И другие эквивалентные операторы. Дольше писать согласен (да и то при подсказке через точку нет проблем),
хуже читать — нет. Так думай перегружен метод для == или это ReferenceEquals.
Я лично предпочитаю единые по написанию функции четко определяющие вид операции вместо перегруженных операций.
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Kh_Oleg, Вы писали:
K_O>>Два замечания: K_O>>Во-первых, в выражении использованы значения всех переменных, кроме массива f. Причем использованы без инициализации. WH>1)Во всех трех примерах написано //тут инициализация. Тебе что больше не кчему предратся? WH>2)Если ты посмотришь внимательно то значение массива f тоже использовано. Оператор *= K_O>>Понятно, что в реальном проекте ты уж наверняка все бы проинициализировал. Только это как-то... неаккуратненько. WH>А нахрена в примерах писать гору не относящегося к делу кода?
А что, для того, чтобы проинициализировать такой супер краткий шаблон надо "гору кода" писать? Так толку тогда с таких кратких выражений...
K_O>>Второе, в твоем "кратком" выражении, за которое ты ратуешь, ни фига не понятно, где переменная типа double, а где — элемент массива. Упаси Бог, когда-нибудь отлаживать ошибку в таком выражении. Зачем нужна такая краткость в ущерб читабельности? WH>А что должно быть понятно в выражении которое писано от балды? В реальной программе будут вполне себе говорящие имена.
Я говорю не про имена переменных, а про то, что не понятно, где просто переменная, а где массив.
K_O>>Не зная, как перегружены операторы для этих массивов абсолютно невозможно сказать, какой элемент массива учавствует в выражении!!! WH>Один раз читаем доку в которой написано что-то типа WH>
WH>Для типа array_t перегружены все арифметические операторы так что запись вида arr1*arr2 трактуется как поэлементное умножение массивов. А запись вида const*arr трактуется как поэлементное умножение массива на константу.
WH>Я знаю что из меня плохой писатель хелпов. Но скажи что тебе после прочтения этого будет не понятно в выражении тапа WH>arr1=arr2*const1-arr3/const2; WH>Ы?
Я вообще-то не очень люблю доки читать. Если надо в чем-то разобраться — смотрю в исходники. Доки часто просто отстают от реализации или там не все нюансы отражены. Но дело не в этом. Для того, чтобы понять как работает приведенный тобой шаблон я должен смотреть либо в доки, либо в исходники. А вот если бы вместо "*" использовался метод, скажем, MultiplyItemByItem, то никуда не надо было лезть и в чем-то разбираться. Такой код читался бы проще.
K_O>>Вот для базовых (примитивных) типов операторы должны быть определены. Но не для составных типов, определяемых программистом! WH>Категорически не согласен. Допустим я реализовал библиотеку для работы с числами в несколько сотен быйт и что мне теперь для них нельзя операторы перегрузить?
Я бы не стал так делать. Потому как работа с такими числами — это нетривиальные алгоритмы, которые, думается мне, потребуют особого порядка их использования и будут обладать некоторыми ограничениями. Все равно мне придется найти доп. инфу по ним, чтобы эффективно использовать твою библиотеку. Так пусть эта инфа находится прямо в тексте программы в виде имени метода.
WH>А взят тотже boost::spirit когда надо быстро написать не сложный парсер то эта штука очень удобна. Но он небыл бы возможен без перегрузки операторов.
Не видел, не знаю.
K_O>>Умножение матриц — это целый алгоритм, к тому же, перемножение матриц, операция некоммутативная (A*B != B*A), а из текста этого не видно. Понятно, что часто хочется записать выражение в программе в виде, близком к виду формулы из книги. Но тогда, для того, чтобы понять, что здесь происходит надо будет эту самую книгу перечитать. WH>Я вобще не понимаю как можно писать программу для предметной области хотябы поверхностно не разобравшись в ней?
Да не об этом речь...
Я говорю о том, что разные по реализации алгоритмы должны и в тексте программы выглядеть по-разному, т.е. иметь разные имена.
Здравствуйте, gbear, Вы писали:
G>Дело не только и не столько в семантике — хотя это тоже проблема.
G>Но, что за смысл Вы вкладываете в понятие "текстовая или графическая нотация" — ИМХО, любая нотация либо то, либо другое
Текстовая нотация — это подмножество графической.
G>И мне видется очень важным, что бы ко всему прочему, "программисткой нотацией" можно было с легкость пользоваться вооружившись "карандашом и листком бумаги".
Чтобы нотация была однозначной нужно для всего (потенциально бесконечного) числа понятий заводить свой символ Разумеется, это на практике затруднительно, поэтому приходиться обходиться двумя алфавитами и нпарой сотен специальных символов, навешивая на них различные значения.
G>Но опять же... повторюсь... в этом вопросе мы напоминаем мне филогов с их определением ямба и хрея С их точки зрения, наверное, оно тоже "достаточно формализованно"... покрайней мере моя жена так и не поняла почему я долго над этим определением смеялся... Рискну процетировать (не пинать за оффтоп, пожалуйста, ИМХО, оно весьма поучительно).
На самом деле у нас ситуация гораздо серьезнее из за того, что в общении учавствуют не только люди. И требования к точности и объемы текстов у нас гораздо больше. Поэтому лично я чувствую необходимость не столько в какой-то письменной нотации удобной для понимания человеком, сколько в способе кодирования информации, позволяющим преобразования межу различными представлениями (языками, нотациями etc.) без потерь.
Подробнее сейчас описывать времени нет, но я как раз сейчас это направление исследую. Если интересно могу расписать подробнее. "Понятия" в моем посте о "минимальных контекстно-независимых решениях" как раз относится к этой теме.
Здравствуйте, WolfHound, Вы писали:
K_O>>Не зная, как перегружены операторы для этих массивов абсолютно невозможно сказать, какой элемент массива учавствует в выражении!!! WH>Один раз читаем доку в которой написано что-то типа WH>
WH>Для типа array_t перегружены все арифметические операторы так что запись вида arr1*arr2 трактуется как поэлементное умножение массивов. А запись вида const*arr трактуется как поэлементное умножение массива на константу.
Кстати, такие вещи вроде-бы принято через итераторы делать... Тогда ты не будешь привязан к представлению контейнера.
Здравствуйте, Kh_Oleg, Вы писали:
K_O>А что, для того, чтобы проинициализировать такой супер краткий шаблон надо "гору кода" писать? Так толку тогда с таких кратких выражений...
Зачем писать код который не относится к теме?
K_O>Я говорю не про имена переменных, а про то, что не понятно, где просто переменная, а где массив.
А я тебе говорю что из имен переменных ясно где что.
K_O>Я вообще-то не очень люблю доки читать. Если надо в чем-то разобраться — смотрю в исходники. Доки часто просто отстают от реализации или там не все нюансы отражены.
Плохой пожход. Если доки есть то их надо прочитать. Даже если они и отстали то всеравно будет легче разобратся с исходниками. K_O>Но дело не в этом. Для того, чтобы понять как работает приведенный тобой шаблон я должен смотреть либо в доки, либо в исходники. А вот если бы вместо "*" использовался метод, скажем, MultiplyItemByItem, то никуда не надо было лезть и в чем-то разбираться. Такой код читался бы проще.
Это не то что прочитать... это написать трудно
Человек просто запутается в такой записи.
даже если переписать так(пока переписывал исправил несколько ошибок)
ой как далеко. WH>>А взят тотже boost::spirit когда надо быстро написать не сложный парсер то эта штука очень удобна. Но он небыл бы возможен без перегрузки операторов. K_O>Не видел, не знаю.
А ты скачай boost да посмотри.
Например так задается грамматика калькулятора
EBNF грамматика прямо на С++...
Да по исходникам ты в ней не разберешься... Их там очень много(1,433,069 байт)... Читайте доки. Они рулез.
Зато как клиентский код выглядит... просто прелесть.
K_O>Я говорю о том, что разные по реализации алгоритмы должны и в тексте программы выглядеть по-разному, т.е. иметь разные имена.
Зачем?
Какая разница что складывать два вектора или два числа? И то и другое сложение. Дык зачем для векторов вводить ужасную функцию типа AddVectorVector?
Я еще понимаю если ввести для векторов функции dot и cross ибо умножение векторов бывает скалярное и векторное.
Причем dot и cross можно и без всяких префиксов если поместить их в один неймспейс с вектором тогда будет работать ADL
WH>>Для типа array_t перегружены все арифметические операторы так что запись вида arr1*arr2 трактуется как поэлементное умножение массивов. А запись вида const*arr трактуется как поэлементное умножение массива на константу.
INT>Кстати, такие вещи вроде-бы принято через итераторы делать... Тогда ты не будешь привязан к представлению контейнера.
В данном случае весь смысл этой библиотеки в том чтобы не писать циклы ручками. И уж темболие для случая
int size=10000;
array_t<float> a(size);
array_t<float> b(size);
array_t<float> c(size);
array_t<float> d(size);
array_t<float> e(size);
array_t<float> f(size);
float x;
float y;
float z;
//тут инициализацияf*=(a/x+5)*b-(y*c-d/5)/e-z;//Этот велосипед нужен только ради такой записи
//что эквивалентно (без перегрузки операторов)
for(int i=0;i<size;++i)
f.at(i)*=(a.at(i)/x+5)*b.at(i)-(y*c.at(i)-d.at(i)/5)/e.at(i)-z;
не связоватся с итераторами ибо код будет не просто страшным, а очень страшным.
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Serginio1, Вы писали:
S> Перегрузка не всегда понятна и очевидна. Кроме того при поиске кода в исходниках по функции легче найти ее исходный код.
В кривой либе может быть. Но то что некоторые орлы криво используют перегрузку не повод от нее отказыватся. S> и чем Equals хуже == ????? И другие эквивалентные операторы. Дольше писать согласен (да и то при подсказке через точку нет проблем),
Тем что писать дольше. И выразительность меньше. S> хуже читать — нет. Так думай перегружен метод для == или это ReferenceEquals.
В С++ таких проблем нет. Ибо всегда сравниваются объекты. Указатели тоже объекты. S> Я лично предпочитаю единые по написанию функции четко определяющие вид операции вместо перегруженных операций.
см соседнй пост
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
K_O>>Я говорю не про имена переменных, а про то, что не понятно, где просто переменная, а где массив. WH>А я тебе говорю что из имен переменных ясно где что.
K_O>>Я вообще-то не очень люблю доки читать. Если надо в чем-то разобраться — смотрю в исходники. Доки часто просто отстают от реализации или там не все нюансы отражены. WH>Плохой пожход. Если доки есть то их надо прочитать. Даже если они и отстали то всеравно будет легче разобратся с исходниками.
Качественно оформленный исходный код — лучшая документация. И на 100% отражает суть реализации.
K_O>>Но дело не в этом. Для того, чтобы понять как работает приведенный тобой шаблон я должен смотреть либо в доки, либо в исходники. А вот если бы вместо "*" использовался метод, скажем, MultiplyItemByItem, то никуда не надо было лезть и в чем-то разбираться. Такой код читался бы проще. WH> WH>
WH>Это не то что прочитать... это написать трудно WH>Человек просто запутается в такой записи.
Здесь так: если отстаивать свою точку зрения путем доведения до идиотизма доводов оппонента, то лучше сразу закончить дискуссию.
Я надеюсь, что разговариваю с человеком, умеющим аргументированно спорить.
А возражение по теме таково:
for (int i = 0; i < array_size; i++)
f[i] *= (a[i] / x + 5) * b[i] - (y * c[i] - d[i] / 5) / e[i] - z;
WH>>>А взят тотже boost::spirit когда надо быстро написать не сложный парсер то эта штука очень удобна. Но он небыл бы возможен без перегрузки операторов. K_O>>Не видел, не знаю. WH>А ты скачай boost да посмотри.
Мне уже и STL'ного отстоя хватает, это время пригодится для более важных целей.
WH>Например так задается грамматика калькулятора WH>
WH> Skipped.
WH>
WH>EBNF грамматика прямо на С++...
Ты им часто пользуешься?
WH>Да по исходникам ты в ней не разберешься...
Это вообще приговор библиотеке и выговор разработчикам. Если я по исходникам не разберусь, то и сами разработчики этой либы через некоторое время отсутствия практики работы с boost перестанут понимать в чем дело.
K_O>>Я говорю о том, что разные по реализации алгоритмы должны и в тексте программы выглядеть по-разному, т.е. иметь разные имена. WH>Зачем? WH>Какая разница что складывать два вектора или два числа? И то и другое сложение.
Общего у них только название. Сложение чисел и сложение векторов — принципиально разные операции даже в математике.
WH>Дык зачем для векторов вводить ужасную функцию типа AddVectorVector?
Математический термин "сложение векторов" по-английски звучит так: composition of vectors.
Стало быть не AddVectorVector, а Compose. WH>Я еще понимаю если ввести для векторов функции dot и cross ибо умножение векторов бывает скалярное и векторное.
И не dot и cross, а SclarProduct и CrossProduct.
Здесь хочу сказать еще вот что: важность правильного именования идентификаторов трудно переоценить. Причем очень важно добиваться того, чтобы имя метода не примерно отражало реализацию, а в точности соответствовало ей. Порой добиться этого непросто. Но зато такая тщательность приводит к тому, что код становится читабельным и понятным.
WH>>>Для типа array_t перегружены все арифметические операторы так что запись вида arr1*arr2 трактуется как поэлементное умножение массивов. А запись вида const*arr трактуется как поэлементное умножение массива на константу.
INT>>Кстати, такие вещи вроде-бы принято через итераторы делать... Тогда ты не будешь привязан к представлению контейнера.
WH>f*=(a/x+5)*b-(y*c-d/5)/e-z;//Этот велосипед нужен только ради такой записи WH>//что эквивалентно (без перегрузки операторов) WH>for(int i=0;i<size;++i) WH> f.at(i)*=(a.at(i)/x+5)*b.at(i)-(y*c.at(i)-d.at(i)/5)/e.at(i)-z; WH>[/ccode] WH> В данном случае весь смысл этой библиотеки в том чтобы не писать циклы ручками.
Так все эти перегрузки операторов нужны только для того, чтобы сэкономить ОДНУ (!!!!) строчку?
Я скажу еще вот что: без перегрузки мы имеем один цикл, а с перегрузкой — столько циклов, сколько использовано перегруженных операторов. Из-за сомнительной красоты кода мы еще жертвуем и производительностью.
WH> В С++ таких проблем нет. Ибо всегда сравниваются объекты. Указатели тоже объекты.
Согласно принципам ООП
f*=(a/x+5)*b-(y*c-d/5)/e-z;
Ну зачем так
f= f.mull( a.div(x).add(5).mull(b).sub( y.mull(c).sub(d.div(5)) ).div(e).sub(z) )
Чуть длинее, но понимание это уже дело привычки.
Кроме того, теже mull,add,sub могут быть сами перегружены, а если им давать нормальные имена то вполне.
Небольшой пример из C#. Свойства индексаторы могут быть только this (Items). И различаться только параметрами.
Но реально это могут быть различные свойства. Зачем там нужна перегрузка??? Кроме того разные свойства но с одинаковыми параметрами в этом случае не прокатывают.
Я во многом с тобой согласен, но к перегрузке операторов как и функций нужно подходить очень акуратно и выверенно.
Equals легко заменяет ==, и по читабельности ну ни коим образом не уступает.
А с точки зрения шаблонов будет проходить и тот и другой код.
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
S>> и чем Equals хуже == ????? И другие эквивалентные операторы.
Тем что текст становится меньше похож на математическую формулу. (Только пожалуйста, не надо в сотый раз про паскалевское сравнение). Кстати, MOD вместо % хуже по той же причине.
Здравствуйте, Kh_Oleg, Вы писали:
K_O>Так все эти перегрузки операторов нужны только для того, чтобы сэкономить ОДНУ (!!!!) строчку?
Ну одну а столько сколько выражений есть в программе. K_O>Я скажу еще вот что: без перегрузки мы имеем один цикл, а с перегрузкой — столько циклов, сколько использовано перегруженных операторов. Из-за сомнительной красоты кода мы еще жертвуем и производительностью.
Ты недооцениваешь С++. Цикл будет один.
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Kh_Oleg, Вы писали:
WH>>Плохой пожход. Если доки есть то их надо прочитать. Даже если они и отстали то всеравно будет легче разобратся с исходниками. K_O>Качественно оформленный исходный код — лучшая документация. И на 100% отражает суть реализации.
А кто спорит? Просто если есть дока то из нее гораздо проще понять общию идеологию системы. И тогда разобратся с исходниками будет на порядок проще. Как бы они небыли хорошо оформлунны. K_O>>>Но дело не в этом. Для того, чтобы понять как работает приведенный тобой шаблон я должен смотреть либо в доки, либо в исходники. А вот если бы вместо "*" использовался метод, скажем, MultiplyItemByItem, то никуда не надо было лезть и в чем-то разбираться. Такой код читался бы проще. K_O>Здесь так: если отстаивать свою точку зрения путем доведения до идиотизма доводов оппонента, то лучше сразу закончить дискуссию.
Это была лишь демонстрация предложеного тобой метода.
K_O>А возражение по теме таково: K_O>
А теперь добавь сюда дебужную проверку того что размер всех массивов в выражении одинаковый.
WH>>А ты скачай boost да посмотри. K_O>Мне уже и STL'ного отстоя хватает, это время пригодится для более важных целей.
А слабо аргументировано обосновать отстойность STL?
Я надеюсь, что разговариваю с человеком, умеющим аргументированно спорить.(С) Ты.
WH>>EBNF грамматика прямо на С++... K_O>Ты им часто пользуешься?
Не очень. Но иногда бывает.
WH>>Да по исходникам ты в ней не разберешься... K_O>Это вообще приговор библиотеке и выговор разработчикам. Если я по исходникам не разберусь, то и сами разработчики этой либы через некоторое время отсутствия практики работы с boost перестанут понимать в чем дело.
Для того чтобы разобратся в полутра метрах исходников даже учитывая что они очень качественно написаны, да еще и не прочитав предварительно доки Не реально.
А прочитав доку к спириту исходники изучать уже не обязательно.
А написана она очень качественно.
K_O>Общего у них только название. Сложение чисел и сложение векторов — принципиально разные операции даже в математике.
Не вижу принципиальной разници. Да и в математике они записываются одинаково.
K_O>И не dot и cross, а SclarProduct и CrossProduct.
А в D3DX они называются D3DXVec3Dot и D3DXVec3Cross соответственно.
Я взял терминологию от туда.
K_O>Здесь хочу сказать еще вот что: важность правильного именования идентификаторов трудно переоценить. Причем очень важно добиваться того, чтобы имя метода не примерно отражало реализацию, а в точности соответствовало ей. Порой добиться этого непросто. Но зато такая тщательность приводит к тому, что код становится читабельным и понятным.
Говоришь то ты правильно но твом методы добится этого мягко говоря сомнительны.
Не плодите сущьности без необходимости (С) Не помню.
Зачем вводить сущьность ComposeVectorVector когда есть всем понятная сущьность + ? Не понимаю.
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
[]
K_O>Оператор сложения для строк, означающий конкатенацию — это, пожалуй, единственное применение перегрузки операторов, где оно действительно необходимо. А все потому, что в ЯП строка должна быть базовым типом! Таким как char, int, double. Так и string. K_O>Вот для базовых (примитивных) типов операторы должны быть определены. Но не для составных типов, определяемых программистом!
Я практически не вижу разницы между перегрузкой операторов и перегрузкой функций. Функция "divide" не имеет никаких преимуществ перед оператором "/" для пользовательского типа. Как раз наоборот.
Перегрузка функций (операторов) может быть проявлением статическго полиморфизма. Такой полиморфизм подразумевает поддержку операций над объектами различного типа с использованием общего синтаксиса (соответствующие функции/операторы имеют одинаковые имена, кол-во аргументов).
Представим класс-тип BigNumber, для которого перегружены мат. операторы "+", "/", etc, вместо того чтобы определять функции "add", "divide", etc. Таким образом BigNumber поддерживает статический интерфейс встроенных числовых типов. Что это дает:
1. Пользователь может использовать привычный интуитивно понятный синтаксис для выражений с объектами BigNumber.
2. Достаточно совсем небольших изменений, чтобы код, использующий BigNumber стал работать с int или с VeryBigNumber. И не надо лазить по всему коду и править "divide" на "/".
3. В С++ эти зачатки статического полиморфизма с помощью шаблонов (или, прости Господи, макросов) мы можем использовать по полной. Например классом BigNumber можно будет параметризировать шаблон complex. Действительная и мнимая части будут храниться в двух переменных типа BigNumber, а комплексная арифметика реализована в терминах мат. операторов над этими переменными.
На практике перегрузка (не только операторов, но и функций!) может вызывать определенные неприятности в случае, когда за идентично выглядящими интерфейсами скрываются различные семантические допущения. Но точно также виртуальная функция вместо ожидаемого действия может отформатировать винчестер
[]
WH>>ЗЗЫ А тех кто перегружает операторы не интуетивным образом надо сжигать на костре и предавать анафиме... K_O> Но почему язык позволяет таким индивидуумам так хулиганить?
Язык позволяет хулиганить с функциями ничуть не меншье.
ЗЫ И мне непонятно, чего ты стал придираться к неинициализированным переменным у WH. Если бы он использовал функции вместо операторов, то эти переменные инициализировались бы сами собой?
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Serginio1, Вы писали:
S>> f= a.div(x).add(5).mull(b).sub( y.mull(c).sub(d.div(5))).div(e).sub(z) WH>А y это float...
А вот еще и перегрузка методов
Тады
f= a.div(x).add(5).mull(b).sub( c.mull(y).sub(d.div(5))).div(e).sub(z)
Но лучше тогда
f= a.VectorDiv(x).IntAdd(5).VectorMull(b).VectorSub( c.FloatMull(y).VectorSub(d.IntDiv(5))).VectorDiv(e).VectorSub(z)
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня