IT

스칼라의 연산자 오버로드가 "좋은"것이지만 C ++의 "나쁜"것은 무엇입니까?

lottoking 2020. 6. 8. 08:03
반응형

스칼라의 연산자 오버로드가 "좋은"것이지만 C ++의 "나쁜"것은 무엇입니까?


C ++에서 연산자 오버로딩은 많은 사람들에 의해 A Bad Thing (tm)으로 간주되며, 새로운 언어에서는 반복되지 않는 실수입니다. 확실히, 그것은 자바를 설계 할 때 특별히 떨어 뜨린 기능 중 하나였습니다.

스칼라에 대해 읽기 시작 했으므로 연산자 오버로드와 매우 흡사합니다 (기술적으로는 연산자가없고 함수 만 있기 때문에 연산자 오버로드가 없지만). 그러나 C ++에서 연산자 오버로드와 질적으로 다르지 않은 것으로 보입니다. 여기서 연산자를 특수 함수로 정의합니다.

그래서 제 질문은 스칼라에서 "+"를 정의하는 아이디어가 C ++에서보다 더 나은 아이디어로 만드는 이유는 무엇입니까?


C ++은 C의 진정한 파란색 연산자를 상속합니다. 즉, 6 + 4의 "+"는 매우 특별합니다. 예를 들어, 그 + 함수에 대한 포인터를 얻을 수 없습니다.

반면 스칼라는 그런 식으로 연산자가 없습니다. 단어 이름이 아닌 기호에 대해 메소드 이름과 약간의 우선 순위를 정의 할 때 유연성이 뛰어납니다. 따라서 기술적으로 스칼라에는 운영자 과부하가 없습니다.

호출하고자하는 것이 무엇이든, 연산자 오버로딩은 본질적으로 C ++에서도 나쁘지 않습니다. 문제는 나쁜 프로그래머가 그것을 남용 할 때입니다. 그러나 솔직히 말해서 프로그래머 오버로드를 남용하는 프로그래머의 능력을 빼앗아도 프로그래머가 남용 할 수있는 모든 것을 고치는 버킷이 줄어들지는 않는다고 생각합니다. 진정한 대답은 멘토링입니다. http://james-iry.blogspot.com/2009/03/operator-overloading-ad-absurdum.html

그럼에도 불구하고, C ++의 연산자 오버로딩과 스칼라의 유연한 메소드 이름은 IMHO로 인해 스칼라가 덜 학 대화되고 더 학 대화되도록하는 차이점이 있습니다.

C ++에서 고정 표기법을 얻는 유일한 방법은 연산자를 사용하는 것입니다. 그렇지 않으면 object.message (argument) 또는 pointer-> messsage (argument) 또는 function (argument1, argument2)을 사용해야합니다. 따라서 코드에 특정 DSL 스타일을 원한다면 연산자를 사용해야하는 압력이 있습니다.

스칼라에서는 모든 메시지 전송과 함께 접두사 표기법을 얻을 수 있습니다. "객체 메시지 인수"는 완벽하게 적용됩니다. 즉, 부호가 아닌 단어를 사용할 필요가 없습니다.

C ++ 연산자 오버로딩은 기본적으로 C 연산자로 제한됩니다. "+"및 ">>"와 같은 비교적 적은 수의 기호에 광범위한 관련없는 개념을 매핑하도록 사람들에게 압력을 가하는 조작자 만 접두어를 사용할 수 있다는 한계와 결합

스칼라는 메서드 이름으로 유효한 비 단어 기호를 광범위하게 허용합니다. 예를 들어, 쓸 수있는 내장 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 ++에 매핑하려면 이미 매우 다른 개념을 불러 일으키는 몇 가지 기호가 필요합니다.

물론 이것은 또 다른 종류의 학대에 스칼라를 열어줍니다. 스칼라에서는 원한다면 메소드 이름을 $! & ^ %로 지정할 수 있습니다.

스칼라와 같이 단어가 아닌 함수 및 메소드 이름을 사용하는 데 융통성이있는 다른 언어의 경우 스칼라와 같이 모든 "연산자"는 또 다른 방법 인 Haskell과 프로그래머가 융통성있게 명명 된 우선 순위 및 고정도를 정의 할 수있는 스몰 토크를 참조하십시오. 기능.


C ++에서 연산자 오버로드는 많은 사람들이 A Bad Thing (tm)으로 간주합니다

무지한 사람에 의해서만. 그것은 C ++과 같은 언어에서 절대적으로 필요하며, "순수한"관점에서 시작한 다른 언어들이 디자이너들이 필요로하는 것을 알게되면 그것을 추가했다는 것이 눈에 able니다.


C ++에서 연산자 오버로딩은 보편적으로 나쁜 생각으로 여겨지지 않았습니다. 연산자 오버로딩의 남용은 나쁜 생각으로 여겨졌습니다. 어쨌든 더 자세한 함수 호출로 시뮬레이션 할 수 있기 때문에 언어에서 연산자 오버로드가 실제로 필요하지 않습니다. Java에서 연산자 오버로드를 피하면 Java의 구현 및 사양이 조금 더 단순 해져 프로그래머가 연산자를 남용하지 않아야합니다. Java 커뮤니티에서 운영자 오버로드를 도입하는 것에 대한 토론이있었습니다.

Scala에서 연산자 오버로딩의 장단점은 C ++에서와 동일합니다. 연산자 오버로딩을 적절하게 사용하면보다 자연스런 코드를 작성할 수 있습니다. 그렇지 않은 경우 더 복잡하고 난독 화 된 코드입니다.

참고 : 연산자는 C ++에서 특수 함수로 정의되지 않으며 다른 함수와 같이 작동합니다. 이름 조회에는 몇 가지 차이점이 있지만 멤버 함수 여야하는지 여부와 두 가지 방법으로 호출 할 수 있다는 사실이 있습니다. 1 ) 연산자 구문 및 2) operator-function-id 구문


이 기사- " 긍정적 인 유산 C ++ 및 Java "-귀하의 질문에 직접 답변합니다.

"C ++에는 스택 할당과 힙 할당이 모두 있으므로 모든 상황을 처리하고 메모리 누수를 유발하지 않도록 연산자를 오버로드해야합니다. 실제로는 어렵습니다. 그러나 Java에는 단일 스토리지 할당 메커니즘과 가비지 수집기가있어 연산자 오버로드가 간단합니다." ..

Java는 실수로 (작성자에 따르면) C ++에서는 복잡하기 때문에 연산자 오버로드를 생략했지만 이유를 잊어 버렸습니다 (또는 Java에 적용되지 않았다는 것을 알지 못했습니다).

다행히 Scala와 같은 고급 언어는 개발자에게 동일한 JVM에서 계속 실행하면서 옵션을 제공합니다.


연산자 오버로딩에는 아무런 문제가 없습니다. 실제로 숫자 유형에 연산자 오버로드 없는문제가 있습니다. BigInteger 및 BigDecimal을 사용하는 일부 Java 코드를 살펴보십시오.

그러나 C ++에는이 기능을 남용하는 전통이 있습니다. 흔히 인용되는 예는 비트 시프트 연산자가 오버로드되어 I / O를 수행하는 것입니다.


일반적으로 나쁜 것은 아닙니다.
C #과 같은 새로운 언어에는 연산자 오버로드가 있습니다.

연산자 오버로드가 악용되는 것은 잘못된 것입니다.

But there are also problems with operator overloading as defined in C++. Because overloaded operators are just syntactic sugar for method calls they behave just like method. On the other hand normal built-in operators do not behave like methods. These inconsistency can be cause problems.

Off the top of my head operators || and &&.
The built in versions of these are short-cut operators. This is not true for overloaded versions and has caused some problems.

The fact that + - * / all return the same type that they operate on (after operator promotion)
The overloaded versions can return anything (This is where the abuse sets in, If your operators start to return some arbitrator type the user was not expecting things go down hill).


Operator overloading is not something that you really "need" very often, but when using Java, if you hit a point where you genuinely need it, it'll make you want to rip your fingernails out just so you have an excuse to stop typing.

That code which you've just found overflows a long? Yup, you're going to have to retype the whole lot to make it work with BigInteger. There is nothing more frustrating that having to reinvent the wheel just to change the type of a variable.


Guy Steele argued that operator overloading should be in Java as well, in his keynote speech "Growing a language" - there's a video and a transcription of it, and it's really an amazing speech. You will wonder what he is talking about for the first couple of pages, but if you keep on reading, you will see the point and achieve enlightenment. And the very fact that he could do such a speech at all is also amazing.

At the same time, this talk inspired a lot of fundamental research, probably including Scala - it's one of those papers that everybody should read to work in the field.

Back to the point, his examples are mostly about numeric classes (like BigInteger, and some weirder stuff), but that's not essential.

It is true, though, that misuse of operator overloading can lead to terrible results, and that even proper uses can complicate matters, if you try to read code without studying a bit the libraries it uses. But is that a good idea? OTOH, shouldn't such libraries try to include an operator cheat sheet for their operators?


I believe EVERY answer missed this. In C++ you can overload operators all you want, but you can't effect the precedence with which they're evaluated. Scala doesn't have this issue, IIRC.

As for it being a bad idea, besides precedence issues, people come up with really daft meanings for operators, and it rarely aids readability. Scala libraries are especially bad for this, goofy symbols that you must memorize each time, with library maintainers sticking their heads in the sand saying, 'you only need to learn it once'. Great, now I need to learn some 'clever' author's cryptic syntax * the number of libraries I care to use. It wouldn't be so bad if there existed a convention of ALWAYS supplying a literate version of the operators.


Operator overloading was not a C++ invention - it came from Algol IIRC and even Gosling does not claim it is a bad idea in general.


The only thing known wrong in C++ is the lack of the ability to overload []= as a separate operator. This could be hard to implement in a C++ compiler for what is probably not an obvious reason but plenty worth it.


As the other answers have pointed out; operator overloading itself isn't necessarily bad. What is bad it when it is used in ways that make the resulting code un-obvious. Generally when using them you need to make them do the least surprising thing (having operator+ do division would cause trouble for a rational class's usage) or as Scott Meyers says:

Clients already know how types like int behave, so you should strive to have your types behave in the same way whenever reasonable... When in doubt, do as the ints do. (From Effective C++ 3rd Edition item 18)

Now some people have taken operator overloading to the extreme with things like boost::spirit. At this level you have no idea how it is implemented but it makes an interesting syntax to get what you want done. I'm not sure if this is good or bad. It seems nice, but I haven't used it.


I have never seen an article claiming that C++'s operator overloading is bad.

User-definable operators permit an easier higher level of expressivity and usability for users of the language.


However, it wouldn't seem to be qualitatively different to the operator overloading in C++, where as I recall operators are defined as special functions.

AFAIK, There is nothing special in operator functions compared to "normal" member functions. Of course you only have a certain set of operators that you can overload, but that doesn't make them very special.

참고URL : https://stackoverflow.com/questions/1098303/what-makes-scalas-operator-overloading-good-but-cs-bad

반응형