Что делает оператор Scala, перегружающий “хороший”, но C++ “плохо”?

я использую студию зенда для затмения с созданным в отладчике. Все еще замедляют по сравнению с отладкой с затмением PDT с xdebug. Надо надеяться, они устранят те проблемы, скорость улучшилась по недавним выпускам, но все еще переступание через вещи занимает 2-3 секунды. Панель инструментов Firefox зенда действительно делает вещи легкими (отладьте следующую страницу, текущую страницу, и т.д.). Также это предоставляет профилировщику, который сравнит Вашего кода и предоставит круговые диаграммы, время выполнения, и т.д.

153
задан skaffman 7 September 2009 в 22:21
поделиться

13 ответов

Это оказалось намного проще, чем казалось. Я решил проблему с помощью следующего сообщения в блоге: http://weblogs.asp.net/salimfayad/archive/2008/07/09/linq-to-entities-join-queries.aspx

Ключ Для этого решения нужно применить фильтр названия группы к подмножеству Bands коллекции музыкального стиля.

var result=(from m in _entities.MusicStyle 
            from b in m.Band
            where b.Name.Contains(search)
            select new {
                BandName = b.Name,
                m.ID,
                m.Name,
                m.Description
            });

обратите внимание на строку

from b IN m.Band

Это гарантирует, что вы фильтруете только группы, которые имеют музыкальный стиль.

Спасибо за ваш ответов, но ни один из них не решил мою проблему.

Под этим я подразумеваю, что «+» в 6 + 4 очень особенное. Вы не можете, например, получить указатель на эту функцию +.

Scala, с другой стороны, не имеет таких операторов. У него просто большая гибкость в определении имен методов, плюс немного встроенного приоритета для несловесных символов. Так что технически в Scala нет перегрузки операторов.

Как бы вы это ни называли, перегрузка операторов не является плохой по своей сути, даже в C ++. Проблема в том, что плохие программисты злоупотребляют этим. Но, честно говоря, я придерживаюсь мнения, что лишение программистов возможности злоупотреблять перегрузкой операторов не означает отказа от исправления всех вещей, которыми программисты могут злоупотреблять. Настоящий ответ - наставничество. http://james-iry.blogspot.com/2009/03/operator-overloading-ad-absurdum.html

Тем не менее, есть различия между перегрузкой операторов C ++ и гибким именованием методов Scala, которые, IMHO, делают Scala менее опасным и более опасным.

В C ++ единственный способ получить нотацию in-fix - использовать операторы. В противном случае вы должны использовать объект.сообщение (аргумент) или указатель-> сообщение (аргумент) или функцию (аргумент1, аргумент2). Поэтому, если вам нужен определенный стиль DSLish в вашем коде, тогда вам придется использовать операторы.

В Scala вы можете получить инфиксную нотацию при отправке любого сообщения. «аргумент объектного сообщения» вполне подходит, что означает, что вам не нужно использовать символы, отличные от слов, только для получения инфиксной нотации.

Перегрузка операторов C ++ ограничивается по существу операторами C. В сочетании с ограничением, что только операторы могут использоваться в инфиксе, что заставляет людей пытаться сопоставить широкий диапазон несвязанных понятий с относительно небольшим количеством символов, таких как «+» и «>>»

. Scala допускает огромный диапазон допустимых несловесные символы в качестве имен методов. Например, у меня есть встроенный Prolog-ish DSL, где вы можете написать

female('jane)!         // jane is female
parent('jane,'john)!   // jane is john's parent
parent('jane, 'wendy)! // jane is wendy's parent

mother('Mother, 'Child) :- parent('Mother, 'Child) & female('Mother) //'// a mother of a child is the child's parent and is female

mother('X, 'john)?  // find john's mother
mother('jane, 'X)?  // find's all of jane's children

. Символы: -,!,? И & определены как обычные методы. Только в C ++ & будет действительным, поэтому попытка сопоставить этот DSL с C ++ потребует некоторых символов, которые уже вызывают очень разные концепции.

Конечно, это также открывает Scala для другого рода злоупотреблений. В Scala вы можете назвать метод $! & ^%, Если хотите.

Для других языков, которые, как Scala, гибки в использовании не-словарных функций и имен методов, см. Smalltalk, где, как и Scala, каждый "

238
ответ дан 23 November 2019 в 22:03
поделиться

Как указывали другие ответы; Сама по себе перегрузка операторов не обязательно плохо. Что плохо, когда его используют таким образом, чтобы полученный код не был очевиден. Обычно при их использовании вам нужно заставить их делать наименее неожиданные вещи (наличие оператора + do деление вызовет проблемы для рационального использования класса) или, как говорит Скотт Мейерс:

Клиенты уже знают, как типы вроде int behavior, поэтому вам следует стремиться к пусть ваши типы ведут себя одинаково всякий раз, когда это разумно ... Когда в сомневаюсь, делай как ints . (Из пункта 18 Эффективного C ++ 3-го издания)

Теперь некоторые люди довели перегрузку операторов до крайности с помощью таких вещей, как boost :: spirit . На этом уровне вы понятия не имеете, как это реализовано, но он создает интересный синтаксис для выполнения того, что вы хотите. Я не уверен, хорошо это или плохо. Вроде неплохо, но не пользовался.

2
ответ дан 23 November 2019 в 22:03
поделиться

Перегрузка операторов не была изобретением C ++ - она ​​пришла из Algol IIRC, и даже Гослинг не утверждает, что это вообще плохая идея.

3
ответ дан 23 November 2019 в 22:03
поделиться

Однако это не могло бы качественно отличаться от перегрузки операторов в C ++, где, как я помню, операторы определены как специальные функции.

AFAIK, в операторных функциях нет ничего особенного по сравнению с "обычными" функциями-членами. Конечно, у вас есть только определенный набор операторов, которые вы можете перегрузить, но это не делает их особенными.

1
ответ дан 23 November 2019 в 22:03
поделиться

Эта статья - « Положительное наследие C ++ и Java "- прямо отвечает на ваш вопрос.

" В C ++ есть как выделение стека, так и распределение кучи, и вы должны перегрузить свои операторы, чтобы обрабатывать все ситуации и не вызывать утечки памяти. Действительно сложно. Java, однако,имеет единый механизм выделения памяти и сборщик мусора, что делает перегрузку оператора тривиальной "...

Java по ошибке (по мнению автора) опускает перегрузку оператора, потому что это было сложно в C ++, но забыл почему (или не понимал что это не применимо к Java).

К счастью, языки более высокого уровня, такие как Scala, предоставляют разработчикам возможности, но при этом работают на той же JVM.

18
ответ дан 23 November 2019 в 22:03
поделиться

Перегрузка операторов никогда не считалась плохой идеей в C ++ - просто злоупотребление перегрузкой операторов считалось плохой идеей. На самом деле нет необходимости в перегрузке операторов на языке, поскольку их все равно можно смоделировать с помощью более подробных вызовов функций. Избежание перегрузки операторов в Java сделало реализацию и спецификацию Java немного проще и заставило программистов не злоупотреблять операторами. В сообществе Java ведутся споры о введении перегрузки операторов.

Преимущества и недостатки перегрузки операторов в Scala такие же, как и в C ++ - вы можете писать более естественный код, если правильно используете перегрузку операторов - и более загадочный, запутанный код, если вы этого не сделаете.

FYI: Операторы не определены как специальные функции в C ++,

41
ответ дан 23 November 2019 в 22:03
поделиться

Перегрузка оператора в C ++ считается многими плохим Thing (tm)

Только несведущими. Это абсолютно необходимо в таком языке, как C ++, и примечательно, что другие языки, которые начинали придерживаться «пуристского» взгляда, добавили его, как только их дизайнеры узнали, насколько это необходимо.

65
ответ дан 23 November 2019 в 22:03
поделиться

Вы правы, что разработчики могут строить на собственных машинах.

Но вот некоторые вещи, которые наш сервер сборки покупает нам, и мы вряд ли являемся опытными разработчиками сборки:

  • Проблемы с контролем версий (некоторые из них упоминались в более ранних ответах)
  • Эффективность. Разработчикам не нужно останавливаться, чтобы делать сборки локально. Они могут запустить его на сервере и перейти к следующей задаче. Если сборки большие, то это еще больше времени, когда машина разработчика не занята. Еще лучше для тех, кто занимается непрерывной интеграцией и автоматическим тестированием.
  • Централизация. На нашей машине сборки есть сценарии, которые делают сборку, распространяют ее в среде UAT и даже на стадии производства. Хранение их в одном месте уменьшает проблемы с синхронизацией.
  • Безопасность. Здесь мы не делаем ничего особенного, но я Новые языки, такие как C #, также имеют перегрузку операторов.

    Плохая вещь - злоупотребление перегрузкой операторов.

    Но есть также проблемы с перегрузкой операторов, как это определено в C ++. Поскольку перегруженные операторы - это просто синтаксический сахар для вызовов методов, они ведут себя так же, как и методы. С другой стороны, обычные встроенные операторы не ведут себя как методы. Эти несоответствия могут вызвать проблемы.

    Не в последнюю очередь операторы || и && .
    . Встроенные версии этих операторов являются сокращенными операторами. Это неверно для перегруженных версий и вызвало некоторые проблемы.

    Тот факт, что + - * / все возвращают тот же тип, с которым они работают (после повышения оператора)
    Перегруженные версии могут возвращать все что угодно (здесь и начинается злоупотребление, если ваши операторы начинают возвращать какой-либо тип арбитра, пользователь не ожидал, что все пойдет под откос).

8
ответ дан 23 November 2019 в 22:03
поделиться

Я никогда не видел статьи, в которой утверждалось бы, что перегрузка операторов C ++ - это плохо.

Определяемые пользователем операторы обеспечивают более легкий более высокий уровень выразительности и удобства использования для пользователей языка.

2
ответ дан 23 November 2019 в 22:03
поделиться

Я считаю, что В КАЖДОМ ответе это не было. В C ++ вы можете перегружать операторы сколько угодно, но вы не можете повлиять на приоритет, с которым они вычисляются. У Scala нет этой проблемы, IIRC.

Что касается того, что это плохая идея, помимо проблем с приоритетом, люди придумывают действительно глупые значения для операторов, и это редко помогает читаемости. Библиотеки Scala особенно плохи для этого, глупые символы, которые вы должны запоминать каждый раз, а сопровождающие библиотеки прячут головы в песок, говоря: «Вам нужно выучить это только один раз». Отлично, теперь мне нужно изучить загадочный синтаксис «умного» автора * количество библиотек, которые я хочу использовать. Было бы не так уж плохо, если бы существовало соглашение, согласно которому ВСЕГДА предоставляли грамотную версию операторов.

4
ответ дан 23 November 2019 в 22:03
поделиться

Перегрузка оператора - это не то, что вам действительно "нужно" очень часто, но при использовании Java, если вы достигнете точки, где вам это действительно нужно, это заставит вас вырвать ногти, чтобы у вас был повод перестать печатать.

Тот код, который вы ' Нашла переливов немало? Ага, вам придется перепечатать всю партию, чтобы она работала с BigInteger. Нет ничего более разочаровывающего, чем изобретать велосипед, просто чтобы изменить тип переменной.

7
ответ дан 23 November 2019 в 22:03
поделиться

Единственная ошибка, известная в C ++, - это отсутствие возможности перегружать [] = как отдельный оператор. Это может быть сложно реализовать в компиляторе C ++ по, вероятно, не очевидной причине, но того стоит.

3
ответ дан 23 November 2019 в 22:03
поделиться

Нет ничего плохого в перегрузке оператора. На самом деле, что-то не так с , но не с перегрузкой операторов для числовых типов. (Взгляните на код Java, в котором используются BigInteger и BigDecimal.)

Однако C ++ имеет традицию злоупотреблять этой функцией. Часто цитируемый пример - то, что операторы битового сдвига перегружены для выполнения операций ввода-вывода.

9
ответ дан 23 November 2019 в 22:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: