2010-12-20 108 views
4

我一直在想這個很長一段時間。已經有一大堆他們可以被重載,所以爲什麼不做到底,並允許自定義運算符?我認爲這可能是一個很好的補充。爲什麼C++不允許用戶定義的運算符?

我被告知這會使語言太難編譯。這讓我想知道,無論如何,C++不能真正被設計爲易於編譯,那麼它是否真的可撤銷?當然,如果你使用LR語法分析器和靜態表和文法,如

E → T + E | T 
T → F * T | F 
F → id | '(' E ')' 

它不起作用。在Prolog中,通常使用運算符優先級解析器AFAIK進行分析,可以輕鬆定義新運算符,但語言要簡單得多。現在,語法顯然可以被重寫爲接受identifiers在每一個操作符被硬編碼到語法中的地方。

還有什麼其他的解決方案和解析器方案,還有什麼其他的東西影響了設計決策?

+0

你必須在我猜的地方畫線。是的,如果你曾經試圖編寫一個編譯器,你會明白它們並不容易編碼。 – Matt 2010-12-20 10:27:12

回答

10

http://www2.research.att.com/~bs/bs_faq2.html#overload-operator

這種可能性已經被多次考慮過,但每次我/我們都認爲可能存在的問題超出了可能的好處。

這不是一個語言技術問題。即使我在1983年首先考慮它,我也知道它是如何實施的。然而,我的經驗是,當我們超越最微不足道的例子時,人們似乎對運營商使用的「明顯」含義有着微妙的不同意見。一個典型的例子是a**b**c。假設**已被用來表示取冪。現在應該a**b**c的意思是(a**b)**ca**(b**c)?我認爲答案很明顯,我的朋友們都同意 - 然後我們發現我們不同意哪個決議是明顯的。我的猜測是,這樣的問題會導致微妙的錯誤。

+0

哦,我不知道這個文件!很高興知道,謝謝! – 2010-12-20 10:56:24

+5

已添加相關報價。一般來說,簡單地張貼鏈接作爲答案在SO上不受歡迎。這使得讀者難以得到一個概述(如果有5個不同的答案,並且每個答案都包含一個鏈接而沒有其他任何東西,那麼找出哪些答案是好的,哪些答案是壞的,只是無關緊要),而且還因爲您鏈接的頁面可能會在將來被刪除,或者其上的文本可能會改變。總之,如果你想讓人們對你的答案滿意,那麼你*必須貢獻一些東西。即使它只是您鏈接到的頁面的直接引用 – jalf 2010-12-20 11:35:00

1

這會使語言更加複雜。而這顯然不可取。

不過,退房Boost Spirit。使用大量的模板元編程技巧來製作像你所提到的東西是很有幫助的。

0

其實它的設計很容易解析和編譯。 C有32個定義的關鍵字,其他所有的標記都是函數和變量。

C++只有幾個。人們可以很容易地識別哪個標記是哪個標記,因此知道在使用+標記或其他標記時要查找什麼。

+1

易於解析和編譯?普遍的共識是C++是編寫編譯器最困難的編程語言之一(請參閱http://stackoverflow.com/questions/575143/writing-my-own-c-compiler/575155#575155)。 – 2010-12-20 10:31:04

+0

真的,我簡直不敢相信...... C++運行一個運行時類型推斷子系統,它本身非常複雜,在模板替換中進行的類型推導不是微不足道的,而且還來自純粹的解析步驟,我認爲一些結構是相當令人印象深刻的(函數指針和類型定義是我自己的C++解析器有時會發現它的限制的兩件事)。 – 2010-12-20 10:35:29

+0

與自然語言解析相比,它很容易:),它被設計爲可以被相對容易的機器解析。另一個問題是哪些類似的語言更容易解析。從機器的角度來看,ASM無疑是最簡單的。而且C比C++更容易,因爲它沒有運算符重載和模板。所以公平起見,我們應該與其他OOP語言進行比較,並且與那些語言相比,它們是相對平等的。 – ewanm89 2010-12-20 11:57:54

2

這會比現在更難以編譯。另外,運營商的優先權也會出現問題:您如何定義?您需要一種方法告訴編譯器,用戶定義的運算符優先於其他運算符。

幾乎可以肯定這是可行的,但我認爲C++並不需要其他方式來搬起石頭砸自己的腳:-)

0

的問題,使運營商定製的是,你還必須允許程序員指定操作符應該如何使用的語法。我想在C++類型系統可以幫助一點,但它會幫助解決類似問題的關聯性等

這將使得本已複雜的語言,要複雜得多......

0

這通常是避免的,因爲大多數代碼是由更多的人編寫的,所以代碼應該是「可審查的」,並且它幾乎不是語言的「所需」特徵。

Joel Spolsky對此有一個good article

0

我剛發現它實際上可能實現與重載操作符非常相似的東西。考慮

Vector v, a, b; v = a /vectorProduct/ b; 

原來,您可以通過使用由現有運算符分隔的虛擬類來實現自定義運算符的行爲。 =)

相關問題