简体   繁体   English

自定义容器迭代器是否保证ADL考虑命名空间std?

[英]Do custom container iterators guarantee ADL to consider namespace std?

I have no intention of using this in real code. 我无意在实际代码中使用它。 I promise. 我承诺。

Does the standard guarantee that std namespace is going to be found when a function argument is of type container::iterator and container::iterator isn't a typedef for a built-in type? 当函数参数的类型为container::iteratorcontainer::iterator不是内置类型的typedef时, std是否保证找到std名称空间?

For example 例如

#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?
}

In other words, can the iterator class be defined in such a namespace that std won't be considered by ADL? 换句话说,迭代器类是否可以在这样的命名空间中定义,以便ADL不会考虑std

Thanks in advance. 提前致谢。

The exact type of ::iterator etc. for the standard containers is implementation-defined , so in theory there's nothing stopping it from being a typedef to something outside of std:: (eg a plain pointer). 标准容器的确切类型::iterator等是实现定义的 ,所以从理论上讲,没有什么能阻止它成为std::之外的typedef (例如普通指针)。

I can't find anything else in the standard that suggests that ADL will always work in this case, so -- unless someone corrects me -- I'm going to have to say that the answer is: no, you can't assume that find will be found via ADL. 我在标准中找不到其他任何暗示ADL将始终在这种情况下工作的东西,所以 - 除非有人纠正我 - 我将不得不说答案是:不,你不能假设该find将通过ADL找到。

I believe that the answer is no in the most general case, but yes for most practical implementations. 我相信在最一般的情况下答案是否定的,但对于大多数实际实施来说是肯定的。

According to the C++ ISO standard, §3.4.2/2, there is a notion of an "associated namespace" for an argument, which is defined in a way that includes 根据C ++ ISO标准§3.4.2/ 2,有一个参数的“关联命名空间”的概念,其定义方式包括

If T is a class type (including unions), its associated classes are: the class itself; 如果T是类类型(包括联合),则其关联的类是:类本身; the class of which it is a member, if any ; 它所属的成员,如果有的话 ; and its direct and indirect base classes. 及其直接和间接基类。 Its associated namespaces are the namespaces in which its associated classes are defined. 其关联的命名空间是定义其关联类的命名空间。

This suggests that if the iterator type is really a nested type inside of some container like std::set , then an associated namespace for that iterator in the call to find would be std , since std::set is an associated class and std is the namespace containing set . 这表明如果迭代器类型实际上是某个容器内部的嵌套类型,如std::set ,那么在find的调用中该迭代器的关联命名空间将是std ,因为std::set是一个关联的类, std是包含set的命名空间。 The standard then says that (§3.4.2/2a) 然后标准说(§3.4.2/ 2a)

If the ordinary unqualified lookup of the name finds the declaration of a class member function, the associated namespaces and classes are not considered. 如果名称的普通非限定查找找到类成员函数的声明,则不考虑关联的名称空间和类。 Otherwise the set of declarations found by the lookup of the function name is the union of the set of declarations found using ordinary unqualified lookup and the set of declarations found in the namespaces and classes associated with the argument types . 否则,通过查找函数名称找到的声明集是使用普通非限定查找找到的声明集的并集,以及在与参数类型关联的名称空间和类中找到的声明集

This would mean that you would indeed find the find function in namespace std . 这意味着你确实会在namespace std find函数。

However, this is not guaranteed to work in general. 但是,这不能保证一般工作。 We also have from the spec (§3.4.2) that 我们也从规范(§3.4.2)中得到了

Typedef names and using-declarations used to specify the types do not contribute to this set. 用于指定类型的Typedef名称和using-declarations对此集合没有贡献。

So, as you mentioned in your question, if the iterator type is some sort of typedef , this isn't guaranteed to work correctly. 因此,正如您在问题中提到的,如果迭代器类型是某种typedef ,则无法保证其正常工作。 But barring that, it appears that if you know that the type is not a typedef, it has to be in namespace std or nested in a class in namespace std and should get picked up for ADL. 但除此之外,它看来,如果你知道的类型不是一个typedef,它必须是在namespace std或嵌套在一个类中namespace std和应该得到回升的ADL。 But don't do it! 但是不要这样做! :-) :-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C ++-如何在自定义模板化数据容器中的迭代器上使用Advance()启用ADL? - C++ - How to enable ADL with advance() on iterators in custom templated data container? std :: vector :: reserve是否保证在这种情况下实现不会使迭代器失效? - Does std::vector::reserve guarantee that the implementation will not invalidate iterators in this case? 为自定义迭代器专门化 std::copy - Specialize std::copy for custom iterators 为什么 C++ 标准容器迭代器会忽略其底层容器的一些模板参数? - Why do C++ std container iterators ignore some template parameters of their underlying container? 同一容器的多个自定义迭代器 - Multiple custom iterators for same container 为什么ADL优先于&#39;std namespace&#39;中的函数,但是等于用户定义的命名空间中的函数? - Why does ADL take precedence over a function in 'std namespace' but is equal to function in user-defined namespace? 容器适配器不支持迭代器 - Container Adapters do not support iterators 为非 std:: 命名空间内的距离启用 ADL,并回退到 std::distance - Enabling ADL for distance within a non-std:: namespace, with a fallback to std::distance 保证std :: container :: size_type是std :: size_t - Guarantee that std::container::size_type is a std::size_t 收集更改后,STL迭代器是否保证有效性? - Do STL iterators guarantee validity after collection was changed?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM