如何使用begin()自由函数

时间:2014-01-14 06:36:41

标签: c++ templates c++11 stl generic-programming

我目前正在编写一个处理通用容器的函数模板。由于提到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>

3 个答案:

答案 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::cbeginstd::cend相同。