3

這是問題出現在「C++入門」的§13.3代碼,5天:參數相關查找是在正常範圍查找之前進行的嗎?

void swap(Foo &lhs, Foo &rhs) 
{ 
    using std::swap; 
    swap(lhs.h, rhs.h); // uses the HasPtr version of swap 
    // swap other members of type Foo 
} 

書提及具體的類交換不是由使用聲明所隱藏的現象,是指讀者到§18.2.3:

enter image description here

我讀部分和意識到,這可能與參數依賴查找(ADL)。以下是摘錄:

enter image description here

但我仍然對一些認識模糊。我的問題是:ADL是在正常範圍查找之前,還是在正常範圍查找之後?我目前的理解是,ADL在正常範圍查找之前,因爲否則它應該是使用的std :: swap。如果您認爲我是對的,我需要確認;如果您認爲我錯了,請指出我犯了什麼錯誤。謝謝。

回答

3

ADL以前沒有去過,這不是特別偏愛;除通過常用名稱查找找到的名稱外,還會考慮由ADL找到的名稱。

這些函數名,除了用通常的不合格的名稱查找考慮的範圍和名稱空間擡頭在他們的論據的命名空間。

這意味着所有由ADL發現的名稱和通常的名稱查找將在overload resolution;那麼最佳匹配將被選中。

爲了編譯函數調用,編譯器必須首先執行名稱查找,對於函數來說,它可能涉及依賴於參數的查找,而對於函數模板可能會跟隨模板參數推導。如果這些步驟產生多個候選函數,則執行重載解析來選擇將實際調用的函數。

+0

謝謝。所以不隱藏的關鍵原因是過載。作者應該提到§18.2.3和§18.2.4。如果std命名空間碰巧有一個交換的HasPtr版本,std :: swap會成功地隱藏在外部範圍中定義的用戶定義的交換,對吧? – user5280911

+1

@ user5280911如果你仍然有原始的重載,那麼這個調用將是不明確的。如果沒有,那麼是的,非模板'sts :: swap'將被調用 – Rakete1111

+0

嗨,Rakete1111,謝謝你的評論。我在這裏發佈了一個後續問題:https://stackoverflow.com/questions/46785093/why-can-an-irrelevant-using-declaration-reconcile-overload-ambiguity-with-argu。你可以看一下嗎?謝謝你們! – user5280911