3

我对 using 声明的使用所做的大部分研究,包括阅读各种样式指南的相关部分,都表明是否在 C++ 源文件中使用 using 声明,只要它们出现在所有#includes 之后,就是一个决定权留给编码员。即使是我阅读的风格指南,为了保持一致性,通常会出现在此类常见争议的一侧或另一侧,在这方面也相当灵活。

我的问题是,鉴于这种高度的灵活性,使用一致的风格有多重要?例如,假设作者写了类似

using std::vector;

vector<T> v;

std::cout << v[0] << std::endl;

在 std::vector 上使用而不是在 std::cout 或 std::endl 上使用的不一致应用程序通常被认为是可以接受的,还是会被认为是无纪律的?

4

5 回答 5

7

我认为的全部意义using在于您在名称中使用它的方式不一致。在某些块中经常需要的名称可以使用 using 声明在本地声明,而其他名称则不是。我看不出有什么问题。

将名称声明为具有命名空间范围总是更难接受。我认为,如果明确知道该名称属于特定命名空间,这样就不会将其与其他命名空间混淆,如果它使您的代码更具可读性,那么放置 using 声明不会有什么坏处。

于 2010-09-27T18:29:42.540 回答
2

我现在是明确声明命名空间的强烈支持者(即没有“使用”)

大多数人的命名空间历史都是这样的(在非平凡的,>100kloc 项目中)

纯真 -> 风格 1

using namespace std;

哎哟->风格2

using std::string;
using std::vector;

好的,已经足够了 -> 样式 3

std::string foo = "xxx";
于 2010-09-27T18:37:30.100 回答
1

假设您不说using namespace std;任何地方,我认为大多数开发人员不会关心其他人的代码中的一种或另一种方式。唯一可能困扰他们的是过度使用 std:: 限定符 --- 也就是说,如果你在函数中说“std::vector”20 次,也许是时候“使用 std::vector”了. 否则,没有人应该在意。

有时,在我自己的代码中,我会专门使用“std::”限定符来表明这是我使用该标识符的唯一地方。

于 2010-09-27T18:35:21.510 回答
0

我尽量使用using(没有双关语)。

为了节省打字,我喜欢做 typedefs,例如:

typedef std::vector< int > IntVector;
typedef std::vector< Foo > FooVector;
于 2010-09-27T18:36:11.917 回答
0

这与其说是一个答案,不如说是与其他一些一直主张将命名空间明确包含在名称中的答案的对立面。有时,这是一个糟糕的主意。在某些情况下,您希望使用专门针对手头类型(如果存在)的名称,否则使用标准提供的替代名称。

作为一个典型的例子,让我们考虑一个排序函数。如果你对一些 T 类型的对象进行排序,你最终会交换项目。swap(T &, T&)如果它存在,你想使用一个特殊的,template <class T> std::swap否则。

如果您尝试指定要显式使用的交换的全名,则必须指定一个或另一个 - 您指定一个专用版本,并在未定义它自己的类型上实例化您的排序swap 将失败,否则您指定std::swap,并忽略专门为您要排序的类型提供的任何交换。

using虽然提供了摆脱这种困境的方法:

using namespace std;

template <class T>
mysort(/* ... */ ) {

    // ...

    if (less(x[a], x[b])
        swap(x[a], x[b]);

    // ...
}

现在,如果找到 T 的命名空间包含 a swap(T &, T&),它将通过参数相关查找找到,并在上面使用。如果它不存在,那么std::swap将被找到(并使用),因为using namespace std;它也使其可见。

顺便说一句,我认为只需稍作修改,using namespace x;就可以使其几乎完全无害。就目前而言,它将来自该命名空间的名称引入当前范围。如果其中一个恰好与当前作用域中存在的名称相同,则会发生冲突。当然,问题是我们可能不知道命名空间包含的所有内容,因此几乎总是至少有一些潜在的冲突。

修改将被using namespace x;视为好像它创建了一个围绕当前范围的范围,并将该名称空间中的名称引入该周围范围。如果其中一个恰好与当前作用域中引入的名称相同,则不会发生冲突——就像任何其他块作用域一样,当前作用域中的名称将从周围作用域中隐藏相同的名称。

我没有详细考虑过这一点,所以毫无疑问会有一些极端情况需要更加小心地解决,但我认为总体思路可能会让很多事情变得更简单。

于 2010-09-27T19:05:06.197 回答