自定义容器迭代器是否保证ADL考虑命名空间std? [英] Do custom container iterators guarantee ADL to consider namespace std?

查看:164
本文介绍了自定义容器迭代器是否保证ADL考虑命名空间std?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无意在实际代码中使用它。我承诺。

I have no intention of using this in real code. I promise.

当函数参数的类型为<$ c时,标准是否保证找到 std 名称空间$ c> container :: iterator 和 container :: iterator 不是 typedef 对于内置类型?

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?

例如

#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不会考虑code> std ?

In other words, can the iterator class be defined in such a namespace that std won't be considered by ADL?

提前致谢。

推荐答案

我认为在最常见的情况下答案是,但对于大多数实际实施,

I believe that the answer is no in the most general case, but yes for most practical implementations.

根据C ++ ISO标准,§ 3.4.2 / 2,有一个参数的关联命名空间的概念,其定义方式为:包含

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


如果T是类类型(包括联合),则其关联的类是:类本身; 该类是
成员,如果有的话
;及其直接和间接基类。 其关联的命名空间是定义其关联类的命名空间

If T is a class type (including unions), its associated classes are: the class itself; 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.

这表明如果迭代器类型实际上是某个容器内的嵌套类型,如 std :: set ,那么在调用时该迭代器的关联命名空间find 将是 std ,因为 std :: set 是一个关联的类并且 std 是包含 set 的命名空间。然后标准说(§ 3.4.2 / 2a)

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. The standard then says that (§3.4.2/2a)


如果名称的普通非限定查找找到类的声明成员函数,不考虑关联的名称空间和类。否则通过查找函数名称找到的声明集合是使用普通非限定查找找到的声明集合的联合,以及在与参数类型相关联的名称空间和类中找到的声明集合
/ strong>。

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.

这意味着你确实会找到 find 函数在命名空间std

This would mean that you would indeed find the find function in namespace std.

然而, 保证一般不起作用。我们还从规范(§ 3.4.2)中得到

However, this is not guaranteed to work in general. We also have from the spec (§3.4.2) that


Typedef名称和用于指定类型的using-declarations没有贡献到这个集合。

Typedef names and using-declarations used to specify the types do not contribute to this set.

所以,正如你在问题中提到的,如果迭代器类型是某种 typedef ,这不能保证正常工作。但除此之外,如果您知道该类型不是typedef,则它必须位于 namespace std 中或嵌套在中的类中namespace std 并且应该为ADL选择。 但不要这样做!: - )

So, as you mentioned in your question, if the iterator type is some sort of typedef, this isn't guaranteed to work correctly. 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. But don't do it! :-)

这篇关于自定义容器迭代器是否保证ADL考虑命名空间std?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆