2016-08-03 47 views
1

假設您在翻譯單元內定義了一個函數名,該函數的名稱與任何標準庫函數完全匹配。 由於編譯器首先在翻譯單元中查找定義,然後在庫文件中查找,那麼這個原因也會使用自己的函數定義版本還是會導致診斷?C++是否也保留標準庫函數名稱?

+5

這聽起來像使用'使用命名空間std的症狀;'。如果你正在使用[請停止](http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-in-c-considered-bad-practice)。 – NathanOliver

+0

如果您使用自己的名稱空間,則可以重用stl函數名稱。例如'mynamespace {ostream&cout(String str)...}'。然後,您可以使用範圍解析運算符(:)使用您的名稱空間來指定您想要使用哪種cout – pjcognetta

+0

「正好匹配」,就像在「std」名稱空間中引入新符號一樣?這在第17.6.4.2.1節中明確禁止:*「如果程序的行爲是將聲明或定義添加到命名空間'std'」*,則該行爲是未定義的。但是,您可以針對用戶類型專門設計模板。 – peppe

回答

2

不,不會保留名稱空間std中的函數名稱 - 至少不能在名稱空間std以外使用相同名稱的意義上被禁止。

但是,在名稱空間std(除少數情況下,例如專門化某些模板函數外)中放置名稱會導致未定義的行爲。

如果編譯器在調用函數時抱怨模糊不清,其中一個函數與您的函數具有相同的名稱,但位於名稱空間std中,則原因可能是代碼中的using namespace std。其結果是,當編譯器遇到一個名稱時,您的函數和命名空間std中的函數都是有效的匹配項。如果編譯器沒有理由相對於另一個(例如它們接受相同類型的參數),則代碼將不會編譯。在這種情況下,解決方案是從您的代碼中刪除using namespace std - 除了刪除它之外,無法撤消using namespace std的影響。

2

我不知道我是否正確(糾正我,如果我錯了)明白的問題,但是說你有一個功能,像這樣:

void sort(// blah blah 

或者宣告空間std using namespace std(which you should not be doing)

當您在翻譯單元中調用sort(...)時,編譯器將重載定義,在這種情況下,您的函數具有優先權。

但如果要調用通過顯式定義std命名空間(使用範圍解析運算符)的標準庫函數,像這樣

std::sort(// blah blah 

它將使用std庫函數來代替。

+0

@HolyBlackCat我不知道爲什麼'putchar'有這種行爲,但對我來說你的代碼不應該工作,請參閱http://ideone.com/EXJ50I。 – Holt

+1

標準庫沒有特別的優先權。如果'std'中的'sort'被'using namespace std'拉入,並且還有一個用戶定義的函數'sort',則通常的重載規則適用。 –

+0

@ialcuaz - 不,那是不對的。編譯器在調用時處理重載,並查看範圍內的所有聲明。他們如何到達那裏並不重要。 –