[C++] Перегрузка операторов - операторы с одними аргументами, но разны
возвращаемое значение не входит в сигнатуру.
Представь себе оператор vector1 - vector2
Что в результате этой операции получится? Вектор или пойнт?
Компилятор должен ругаться при появлении неоднозначности в том месте - чтобы написали что-нибудь типа (pointvector1-vector2)...
Я тебе уже дал всю необходимую информацию в своем первом посте.
И никакими директивами компилятору это нельзя исправить?
Представь себе, не зависит
В сигнатуру фу4нкции не входит возвращаемое значение - во всех версиях?
А можно придумать приведение типа vector к point?
Кстати, а на своих классах можно определять приведение типов?
Кстати, а на своих классах можно определять приведение типов?Вот именно это я и спросил. Вдруг можно? Я не большой спец по плюсам.
И совершенно понятно, почему запрещено в таком случае такое описание:
point operator -(vector,vector)
vector operator -(vector,vector)
Во первых, чисто логически, "vector1-vector2" <- выражение, а выражение должно иметь тип. У тебя получается, что это выражение имеет толи тип vector, толи point непонятно.
А во вторых, если у тебя есть конструктор point operator =(vector* source что будет в результате point = vector-vector непонятно. Может быть выполнится оператор "point operator -(vector,vector)", а может выполнится и "vector operator -(vector,vector)" + конструктор.
На твоем месте, я бы убрал point operator -(vector,vector и добавил в point конструктор от vector.
Или выпил, как счас модно выражаться , йаду
Кстати, проблема уже решилась - пришлось использовать вместо point operator -(vector,vector) - point operator /(vector,vector)... извращённое и кривое решение...
Компилятор должен выдавать сообщение об ошибке не тогда, когда видит две функции с одинаковыми типами аргументов, но с разными типами возвращаемых значений, а когда действительно натыкается на неоднозначность - что в результате получается два разных выражения с одинаковыми типами аргументоа, с одинаковыми типами возаращаемых значений...Ботай стандарт C++, а потом рассказывай, что тебе должен компилятор.
Кстати, проблема уже решилась - пришлось использовать вместо point operator -(vector,vector) - point operator /(vector,vector)... извращённое и кривое решение...
Судя по твоим рассказам ты вообще не понимаешь логику C++. Никогда и ни при каких обстоятельствах тип выражения не зависит от контекста, в котором это выражение использовано, выгравируй себе на лбу. Тип выражения иногда неявно преобразуется, если тип выражения возможно статически преобразовать в тип, который требуется контекстом.
насчет решения ты прав - извращенное и кривое. Что нельзя было реализовать статическую конверсию vector в point (например конструктором point(const vector&); как тебе вроде бы уже советовали?
В следующийраз, видимо, так и буду делать... или даже просто сделаю point классом на основе vector...
Никогда и ни при каких обстоятельствах тип выражения не зависит от контекста, в котором это выражение использованоА по-моему, было бы логично, если знать, какой тип надо получить, при компиляции ставить вызов той из этих функций, которая возвращает значение именно того типа, который дальше и используется...
Когда я говорю int a=SomeFunc; - очевидно, что SomeFunc(void) должна возвращать именно инт... и что можно произвести конверсию типа int SomeFunc -> int INPUT_void_OUTPUT_int_NAME_SomeFunc(void)... а в другом случае - делать какой-нибудь string INPUT_void_OUTPUT_string_NAME_SomeFunc(void)...
А по-моему, было бы логично, если знать, какой тип надо получить, при компиляции ставить вызов той из этих функций, которая возвращает значение именно того типа, который дальше и используется...Нет, логично бы не было с точки зрения логики языка C++ (Страуструп не даром его так долго придумывал).
Например, что если возвращаемое значение вообще игнорируется? Или если возвращаемые типы разных функций все статически конвертятся в требуемый тип? Когда всего лишь игнорирование возвращаемого значения уже приводит к неоднозначности это полная патология.
Кроме того и без того непростая задача авторов компиляторов усложняется многократно только для того, чтобы добавить почти неюзабельную кривую на всю голову функциональность.
только для того, чтобы добавить почти неюзабельную кривую на всю голову функциональность.Почему "пчти неюзабельную"?
Это у меня так хорошо получается - что по вектору-разности двух векторов легко можно получить точку-разность двух векторов... а если бы разность двух векторов как вектор и как точка были бы совершенно разными вещами, но, тем не менее, имеющими свой естественный смысл?
Кроме того и без того непростая задача авторов компиляторов усложняется многократно только для того, чтобы добавить почти неюзабельную кривую на всю голову функциональность.Расслабься, это же пен-артур.
Это у меня так хорошо получается - что по вектору-разности двух векторов легко можно получить точку-разность двух векторов... а если бы разность двух векторов как вектор и как точка были бы совершенно разными вещами, но, тем не менее, имеющими свой естественный смысл?Как ты себе представляешь естественный смысл того, что запись "2-2" на бумажке может быть равнозначна записи "0" или "(0,0)"? Ты же в математике не можешь умножить столбец на строку, утверждая, что здесь по логике вещей просто надо переставить их местами?
Ладно, вот тебе пример - скалярное и векторное произведение векторов.
И?... В математике они записываются по-разному. И по аналогии в принципе можно их перегрузить и на С++: для и [].
В математике они записываются по-разномуТолько в С++, знаешь ли, нет оператора "х"... пришлось извращатьс, и записыватьвекторное произведение как a&b.
И по аналогии в принципе можно их перегрузить и на С++: для и [].Поясни
скалярное умножение -- operator,
какие проблемы?
скалярное умножение -- operator,В смысле,
a=b,c
?
Так можно?
ПоясниДоботай перегрузку операторов.
А вот так:
a=(b,c)
в самый раз.
векторное умножение -- operator*ИМХО перегружать запятую - это извращение
скалярное умножение -- operator,
какие проблемы?
ну это конечно вопрос стиля
или я что-то не понимаю?
только . не перегружается из приведенного списка
Ладно, вот тебе пример - скалярное и векторное произведение векторов.две совершенно разные операции
если бы даже их каким-то извратным способом можно было бы сделать одинаковым оператором, это было бы очень глупо делать из соображения стиля.
Я вообще не понимаю ваше болезненное пристрастие к операторам. Почему не использовать обычные функции с репрезентативными названиями (типа scalar_product, vector_product)?
Операторы нормальными людьми используются только там, где они логически уместны и не вызывают неоднозначностей и других вопросов, а не что-то типа operator& в качестве векторного произведения.
Программа в первую очередь должна быть легко читаема, и если например использование оператора вызывает логическую неоднозначность (как например operator*(const vertor&,const vertor&); - непонятно скалярное или векторное произведение то операторы в таких случаях не используются.
только . не перегружается из приведенного списканасчет -> согласен, вспомнил
А вот насчет запятой, уточню, может глючит меня, но что-то запомнился как неперегружемый.
A function declaration having one of the following operator-function-ids as its name declares an operator function. An operator function is said to implement the operator named in its operator-function-id.
operator-function-id:
operator operator
operator operator < template-argument-list-opt >
operator: one of
new delete new[] delete[]
+ - * / % ˆ & | ˜
! = < > += -= *= /= %=
ˆ= &= |= << >> >>= <<= == !=
<= >= && || ++ -- , ->* ->
[]
[Note: the last two operators are function call (5.2.2) and subscripting (5.2.1). The operators new[],
delete[], and [] are formed from more than one token.]
туплю немного
но IMHO все равно это извратный стиль перегружать , && ||
А вотда да. Все так. Уже признал.
Я вообще не понимаю ваше болезненное пристрастие к операторамСогласись, программа, в которой написано vector c=a*b - выглядит более удобочитаемой, чем та, где написано vector c=vector_product(a,b).
А неоднозначность при нормальных условиях не возникнет - можно сразу увидеть, пишется vector c=a*b или double c=a*b
Нельзя. Потому что помимо vector c=a*b или double c=a*b ты можешь написать a*b - и было бы глупо запрещать такую возможность.
То есть, не говорить при определении операторов "кошмар, вы определили два оператора с одинаковыми аргументами", а говорит на a*b "не могу определить, какой из двух операторов использовать"
Согласись, программа, в которой написано vector c=a*b - выглядит более удобочитаемой, чем та, где написано vector c=vector_product(a,b).не соглашусь, потому что ИМХО это совсем не так
Что это за звездочка? Моя первая мысль: умножение вектора на число, потому что ни векторное ни скалярное умножение не является логически аналогичным обычному численному умножению, а вот умножение вектора на число является.
А неоднозначность при нормальных условиях не возникнет - можно сразу увидеть, пишется vector c=a*b или double c=a*bкак раз при типичных условиях нельзя, ты написал инициализацию, которая для переменной происходит только один раз
А что если просто написано c=a*b ? Мне что искать объявления a,b,c?
Да конечно, вектора от чисел должны как-то отличаться стилем наименования, но все равно вследствие возможности подобной логической неоднозначности для векторного и скалярного произведения operator* не используется, но operator* вполне логично использовать для умножения вектора на число.
Это все вопросы стиля, что в общем-то личное дело каждого, и я излагаю конечно только свое мнение. Просто с опытом думаю ты придешь примерно к тем же выводам - есть удобная практика, которой многие придерживаются вполне обоснованно, а не потому что "так принято".
и пишешь: int a = f;
Что делать компилятору?
> Но, имхо, лучше отслеживать эти возможности, когда они используются.
Нет. Этого сделать в принципе нельзя. Потому что компилятор не знает, когда что используется. Это знает линкер. И то, если нет динамического связывания.
Но, имхо, лучше отслеживать эти возможности, когда они используются.Еще раз: с точки зрения C++ ошибкой является существование двух разных функций с одинаковыми названиями и аргументами.
То есть, не говорить при определении операторов "кошмар, вы определили два оператора с одинаковыми аргументами", а говорит на a*b "не могу определить, какой из двух операторов использовать"
Можете придумать свой язык программирования и наделять его любой придуманной вами функциональностью, а C++ уже до вас придумали, и вам остается либо пользоваться им, либо не пользоваться. Можете обратиться в комитет стандартизации с предложением этого вашего "усовершенствования", но они несомненно пошлют вас куда подальше, наверно с аргументацией подобной тому, что вы уже здесь прочитали (вероятно более обширно и подробно). Все.
Нет. Этого сделать в принципе нельзя. Потому что компилятор не знает, когда что используется. Это знает линкер. И то, если нет динамического связывания.нее
тут вы имхо не правы
на стадии компиляции конечно же известно какая именно из функций используется, и определяется это по типам аргументов (но конечно не по типу возвращаемого значения о которых линкер как раз в принципе не может ничего знать - как правило.
Компилятор не знает, что где используется, потому что он компилит модули отдельно.
Компилятор не знает, что где используется, потому что он компилит модули отдельно.В C++ в пределах трансляции, в которой присутствует использование некой функции, присутствует также и объявление функции с таким именем (возможно не одной и после разрешения возможной неоднозначности по аргументам, компилятор точно знает какая именно функция используется (но определение этой функции конечно может отсутствовать в данной трансляции, поэтому численное значение адреса этой функции компилятор может конечно не знать т.е. компилятор ссылается на конкретную (возможно внешнюю) функцию, а не на какое-то неоднозначное имя.
Оставить комментарий
kruzer25
Модераторы, плз, не переносите пока тв программинг - ответ нужен сейчас...Как в С++ (компилятор GCC) разрешить определение операторов типа
point operator -(vector,vector)
vector operator -(vector,vector)
При компиляции ругается (error) на втором операторе по поводу того, что оператор "-" с аргументами "вектор, вектор" уже определён... как можно это обойти?