是"使用std :: begin;" 一个好习惯?

Hum*_*awi 3 c++ standards coding-style c++11

正如我所读到的,begin(some_vector)some_vector.begin()阵列支持更标准......而且我也知道,使用using keyword并不是真正理想的行为.但是,我也看到很多代码只包含这两个usings:

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

这被认为是好的还是坏的做法?特别是当许多beginend需要?

Jon*_*ely 7

正如我所读到的,begin(some_vector)some_vector.begin()阵列支持更标准

它不是"更标准",都是100%标准.它更通用,因为它适用于数组,但实际上并不常见的是拥有一个对象而不知道它是一个数组还是一个容器类型.如果你知道某个数组是一个数组然后使用std::begin(a)但是如果你知道某些东西不是数组,那么使用同样适用于数组的表单也没有任何好处.如果您处于可能具有其中任何一个的通用上下文中,则std::begin适用于这两种情况.

using关键字的使用并不是真正理想的行为.

这是值得商榷的.在大多数情况下(例如using namespace foo)避免使用指令有很好的理由,但相同的参数不适用于引入单个名称的使用声明(即using foo::bar).例如,推荐使用的方法std::swap是通过,using std::swap因此using关键字一般不受欢迎.

这被认为是好的还是坏的做法?特别是当需要许多开始和结束时?

我会说,总的来说这是一个坏主意.至于其他的答案解释,它允许beginend通过ADL被发现,但是这并不一定是好事.启用ADL begin并且end可能导致问题,这就是为什么我们for在最后一刻改变基于范围而不使用using std::begin; using std::end;以避免歧义的原因,请参阅N3257了解详细信息.


For*_*veR 6

它可以ADL帮助你.就像是:

template<typename T, typename F>
void apply(T& v, const F& f)
{
   using std::begin;
   using std::end;
   std::for_each(begin(v), end(v), f);
}
Run Code Online (Sandbox Code Playgroud)

所以,我们只能调用apply具有begin/end函数和经典C数组的类型.

在其他情况下,实际上可以using在源文件中使用指令,在很小的范围内等等,但是在头文件中使用它是不好的.


Nia*_*all 5

这被认为是好的做法还是坏的做法?

这在很大程度上取决于上下文;我认为答案同样适用于通过using. 限制使用范围using使得代码更具可读性(例如函数级别范围);按要求使用,谨慎使用。

这里有一个特别有趣的案例与 ADL 相关。

template <class Container>
void func(Container& c)
{
  std::for_each(begin(c), end(c), /* some functor*/);
}
Run Code Online (Sandbox Code Playgroud)

ADL 已经在发挥作用,因为如果容器来自std命名空间,则会找到std::begin和。std::end如果容器来自自定义命名空间,begin并且end可以在该命名空间中找到函数(对于本讨论,我假设容器提供商也提供了这些函数)。

如果容器是普通的 C 风格数组,std::begin(T (&array)[N])则不会找到数组形式,因为 C 风格数组不是std命名空间。在这里引入 ausing std::begin允许代码用于数组和容器。

template <class Container>
void func(Container& c)
{
  using std::begin; // if c is an array, the function will still compile
  using std::end;
  std::for_each(begin(c), end(c), /* some functor*/);
}
// ...
int a[100];
func(a); // works as expected
Run Code Online (Sandbox Code Playgroud)

演示