![](/img/trans.png)
[英]Defining a function in a namespace other than the ADL, “local” or global namespace
[英]Does ADL work for the global namespace?
諸如啟用std
類型輸出的示例解釋了如何使用ADL “注入”某個函數/運算符,具體取決於應用fn / op的類型。
我想知道ADL是否完全適用於全局命名空間,也就是說,在全局命名空間范圍內聲明(或通過using
可用)的類型是否使ADL在全局命名空間中查找匹配函數?
具體來說,這些是等價的。 ADL?:
// 1 - at global namespace scope
struct GlobalType {};
template< class Ch, class Tr>
std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& os, GlobalType const& x)
{
os << ...;
return os;
}
// 2 - within namespace
namespace ecaps {
struct EcapsType {};
template< class Ch, class Tr>
std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& os, EcapsType const& x)
{
os << ...;
return os;
}
}
// 3 - Type brought to global NS via using, function at global scope
namespace other {
struct OtherType {};
}
using other::OtherType;
template< class Ch, class Tr>
std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& os, OtherType const& x)
{
os << ...;
return os;
}
WRT。 全局命名空間范圍不需要ADL :(在現在刪除的答案后更新)
委員會成名的DanielKrügler描述了一個ADL問題 :
這種不合格的調用會產生無限制的名稱查找,因此編譯器會搜索名稱
operator<<
。 從當前名稱空間中開始operator<<
call is uply“ (...) 的詞匯位置開始,以及包含該名稱空間的所有名稱空間(包括全局名稱空間,btw。)和 - ...
EMPH。 礦。 請注意外部名稱空間的描述如何僅被視為“...... 來自詞匯位置 ......”。 他繼續:
...和 - 作為第二個路徑 - 它執行此查找的第二階段,編譯器在此調用中發生的參數類型的所謂關聯命名空間中搜索。
在給出的示例中,搜索的第一階段失敗,因為在
#include <iterator>
存在的點上,任何名稱空間中的這些參數類型都沒有對應的operator<<
。 請注意,您的聲明operator<<
是哪里的電話后點詞法提供operator<<
在一些庫頭的地方發生。 搜索的第二階段也將考慮按照實際函數調用的位置 ,但只有在相關的命名空間。
大膽的恩賜。 礦。 因此,在我看來,ADL適用於全局命名空間是相關的。 當然,我很容易誤解一些事情。
注意:這可能是標准的一種情況,只是沒有明確地以某種方式提及它,因為全局NS就像任何其他命名空間一樣 - 然后它可能不會,我對標准的了解非常有限。
完全忘記我最初的答案,這是完全錯誤的。
從C ++ 11標准,關於ADL的§3.4.2(強調我的):
當函數調用(5.2.2)中的postfix-expression是非限定id時,可以搜索在通常的非限定查找 (3.4.1) 期間未考慮的其他名稱空間,並在這些名稱空間中搜索名稱空間范圍的朋友函數聲明( 11.3)可能沒有其他可見的。
簡而言之,由於非限定查找將始終在全局命名空間中進行搜索,因此ADL將永遠不會應用於全局命名空間 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.