如何使用begin()自由函数

Mar*_*ayr 2 c++ templates stl generic-programming c++11

我目前正在编写一个处理通用容器的函数模板.我想用std::begin()std::end(),因上述原因在这一问题.我的问题是,我是否应该使用:

std::begin( myContainer )
Run Code Online (Sandbox Code Playgroud)

要么:

using namespace std; // Better use: "using std::begin"
begin( myContainer )
Run Code Online (Sandbox Code Playgroud)

或者,换句话说,是否可以begin()std命名空间内重载?我是否应该允许我的函数用户其他地方重载全局命名空间中begin()函数?STL如何处理它?

Pra*_*ian 5

不需要using指令,所以我们假设第二个代码段包含一个using声明.

using std::begin;
Run Code Online (Sandbox Code Playgroud)

如果你要创建自己的容器来使用这个函数模板,提供Container::begin()Container::end()成员函数,那么无论你使用的是第一个还是第二个,它都没有区别.std::begin()std::end()在可用时调用相应的成员函数(§24.7[iterator.range]).

另一方面,如果您要创建一个功能模板,该模板应该适用于任何容器,标准库中的容器或自定义容器; 我建议采用第二种方法.

using std::begin;
begin( myContainer );
Run Code Online (Sandbox Code Playgroud)

请注意,这将使ADL能够为自由函数找到用户定义的重载,begin()end() 在与容器定义相同的命名空间内查找.不应将重载添加到命名空间std或全局命名空间(除非容器定义也在全局命名空间中).在没有这些自由函数重载的情况下,std::begin将调用(因为using declaration)而这又会调用Container::begin().

  • 建议`使用std :: begin;`而不是`using namespace std;`不是更好吗?后者可能会将许多不受欢迎的名字带入范围. (4认同)