![](/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.