![](/img/trans.png)
[英]C++ - How to enable ADL with advance() on iterators in custom templated data container?
[英]Do custom container iterators guarantee ADL to consider namespace std?
我無意在實際代碼中使用它。 我承諾。
當函數參數的類型為container::iterator
且container::iterator
不是內置類型的typedef
時, std
是否保證找到std
名稱空間?
例如
#include <set>
#include <algorithm>
int main()
{
std::set<int> s;
find(s.begin(), s.end(), 0); //do I have a guarantee that std::find will be found?
}
換句話說,迭代器類是否可以在這樣的命名空間中定義,以便ADL不會考慮std
?
提前致謝。
標准容器的確切類型::iterator
等是實現定義的 ,所以從理論上講,沒有什么能阻止它成為std::
之外的typedef
(例如普通指針)。
我在標准中找不到其他任何暗示ADL將始終在這種情況下工作的東西,所以 - 除非有人糾正我 - 我將不得不說答案是:不,你不能假設該find
將通過ADL找到。
我相信在最一般的情況下答案是否定的,但對於大多數實際實施來說是肯定的。
根據C ++ ISO標准§3.4.2/ 2,有一個參數的“關聯命名空間”的概念,其定義方式包括
如果T是類類型(包括聯合),則其關聯的類是:類本身; 它所屬的成員,如果有的話 ; 及其直接和間接基類。 其關聯的命名空間是定義其關聯類的命名空間。
這表明如果迭代器類型實際上是某個容器內部的嵌套類型,如std::set
,那么在find
的調用中該迭代器的關聯命名空間將是std
,因為std::set
是一個關聯的類, std
是包含set
的命名空間。 然后標准說(§3.4.2/ 2a)
如果名稱的普通非限定查找找到類成員函數的聲明,則不考慮關聯的名稱空間和類。 否則,通過查找函數名稱找到的聲明集是使用普通非限定查找找到的聲明集的並集,以及在與參數類型關聯的名稱空間和類中找到的聲明集 。
這意味着你確實會在namespace std
find
函數。
但是,這不能保證一般工作。 我們也從規范(§3.4.2)中得到了
用於指定類型的Typedef名稱和using-declarations對此集合沒有貢獻。
因此,正如您在問題中提到的,如果迭代器類型是某種typedef
,則無法保證其正常工作。 但除此之外,它看來,如果你知道的類型不是一個typedef,它必須是在namespace std
或嵌套在一個類中namespace std
和應該得到回升的ADL。 但是不要這樣做! :-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.