[英]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::iterator
且container::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.