C++中使用std和boost命名空间的最佳实践

3

可能是重复问题:
你更喜欢在C++中使用显式命名空间还是'using'关键字?

我是一名C#开发者,但我的朋友是C++开发者。他向我展示了充斥着像 std::for_eachboost::bind 这样的调用的代码。我在C#中使用过,并认为使用指令可以提高代码的可读性和开发速度。例如,在C# foreach语句之前输入任何命名空间都会很麻烦。

使用这些流行的命名空间的优缺点是什么?

是否将这些命名空间包含进来是最佳实践呢?


1
有很多重复的内容。我认为那个问题不是一个好问题,因为另一种方式的答案很少。 - Puppy
2
请查看此链接:https://dev59.com/gXM_5IYBdhLWcg3wslfs#1265092。 - icecrime
例如,他说如果用户想要定义一个向量类,使用std可能会创建问题,但是有人可能会说创建与STD类相同名称的类是不好的实践。我认为唯一真正的问题是count,因为它可以在任何用户创建的类中使用。现在,是否有足够大的理由在其他地方键入std::以避免与STD count冲突? - Valentin Kuzub
@Valentin:根据我的经验,这确实是一种严肃的最佳实践,特别是在头文件中。你有一定的自由度,只要确保在头文件中不会污染全局命名空间即可。 - Stuart Golodetz
@Valentin:不,使用与标准库中命名冲突的类/函数并不是不良做法。这正是它们最初被放置在std::命名空间中的原因。 - André Caron
显示剩余7条评论
2个回答

10

首先,让我们做两个区分:

1)有使用指令,如using namespace std;和使用声明,如using std::cout;

2)您可以将使用指令和声明放在头文件(.h)或实现文件(.cpp)中

此外,使用指令和声明会将名称带入它们被写入的命名空间中。

namespace blah
{
    using namespace std; // doesn't pollute the *global* namespace, only blah
}

在最佳实践方面,很明显,在全局命名空间中将using指令和声明放入头文件中是一个可怕的不可以。人们会因此厌恶你,因为任何包含该头文件的文件都会污染其全局命名空间。
在实现文件中放置using指令和声明要稍微容易接受一些,尽管这可能会使代码变得不那么清晰。一般来说,在这种情况下,你应该更喜欢使用声明而不是使用指令。我个人的偏好是始终指定命名空间,除非它特别长(然后我可能会被诱惑)。
在头文件中,如果每次键入名称空间都变得非常繁琐,你可以引入“本地”名称空间,例如:
namespace MyLocalName
{
    using namespace boost;

    class X
    {
        // can use things from boost:: here without qualification
    };
}

using MyLocalName::X; // brings X back into the global namespace

但是不要将 using namespace boost; 或者相当的代码放在会将Boost中所有东西都拖入全局命名空间的地方,以免影响其他人。


头文件并不成问题。很明显它们不是一个好的使用候选。问题在于 - 一般的C++程序员对此的看法,我相信一些重要的公司有编码标准,所以我想知道他们对此有何看法。我认为这不是程序员个人依赖性的问题,也不是公司依赖性的问题。 - Valentin Kuzub
1
@Valentin: 好吧,Google的样式指南有关此事的说明,供参考:http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml。我不是完全同意其中的所有内容,但在这个问题上似乎还是很明智的。 - Stuart Golodetz
是的,就我所看到的,他们对此非常明确。我猜想,考虑到我收到的信息,这可以称为故事的结束,让我们使用gogo std::for_each! - Valentin Kuzub
很高兴能帮到你。顺便说一下,对于其他可能会阅读此内容的人,我为上面的链接错误表示歉意--显然需要删除尾随的角括号,抱歉(我无法再编辑它)。 - Stuart Golodetz
只是为了补充答案。对于较长的命名空间,您可以始终使用别名。例如,“namespace bf = boost :: filesystem; bf :: file_size(“test”);” - daveraja

0

我反对使用using namespace语句,除非是在函数体内的局部使用。在每个标识符前写全限定命名空间并不麻烦,除非你每天要写500行以上的代码。


2
这并不是说编写它很麻烦——只是在某些情况下阅读它可能会很麻烦。例如,当创建 Boost 多索引容器时,完全限定所有内容会使结果代码难以理解。就个人而言,在这种情况下使用 using 有一个非常好的理由,前提是您不会污染任何不应该污染的名称空间。 - Stuart Golodetz
2
相比之下,我发现剥离命名空间的代码很难阅读,甚至会想知道没有带前缀“std::”的“string”是从哪里来的。 - ognian
@ognian:总的来说,我完全同意你的观点——在我的代码中很少使用“using”。不过,在某些情况下,我认为它是可以被证明是合理的。 - Stuart Golodetz
在使用长命名空间名称或深度(即2级以上)的命名空间嵌套时,完全限定所有名称通常会变得繁琐。我不介意一直输入std::vector,但如果它是standard::containers::vector,那么我就非常倾向于在各个地方放置using指令。 - André Caron
@André:好观点,特别是说“到处都是”- 我只会将“using”指令放在函数体中,当长的命名空间被使用超过两次时。 - ognian
@ognian:那通常是我做的 :-) - André Caron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接