我目前正在编写一个处理通用容器的函数模板。由于提到in this question的原因,我想使用std::begin()
和std::end()
。我的问题是,我是否应该使用:
std::begin( myContainer )
或者:
using namespace std; // Better use: "using std::begin"
begin( myContainer )
或者换句话说,是否可以在begin()
命名空间内重载std
?我是否应该允许我的函数用户在其他地方重载全局命名空间中的begin()
函数? STL如何处理它?</ p>
答案 0 :(得分:5)
不需要using
指令,所以我们假设第二个代码段包含using
声明。
using std::begin;
如果您要创建自己的容器以使用此功能模板,请提供Container::begin()
和Container::end()
成员函数,然后无论您使用的是第一个还是第二个,它都没有区别。 std::begin()
和std::end()
将在可用时调用相应的成员函数(§24.7[iterator.range] )。
另一方面,如果您要创建一个功能模板,该模板应该适用于任何容器,标准库中的容器或自定义容器;我建议采用第二种方法。
using std::begin;
begin( myContainer );
请注意,这将使ADL能够在与容器定义相同的命名空间内查找自由函数begin()
和end()
的用户定义重载。不应将重载添加到名称空间std
或全局名称空间(除非容器定义也在全局名称空间中)。如果没有这些自由函数重载,则会调用std::begin
(因为using declaration
),而这又会调用Container::begin()
。
答案 1 :(得分:4)
在std
命名空间中重载某些东西是不可行的,只允许特化。如果您要启用ADL
,可以使用
using std::begin;
begin(myContainer)
答案 2 :(得分:4)
对于自定义容器,std::begin
实际上可以在您的容器中调用begin
。所以如果你有MyContainerClass::begin
就够了。与std::end
和常量迭代器版本std::cbegin
和std::cend
相同。