我在使用声明时所做的大部分研究,包括阅读各种样式指南的相关部分,表明是否在C ++源文件中使用声明,只要它们出现在所有#includes之后,是一个留给编码员的决定。即使是我阅读过的风格指南,为了保持一致性,这些风格指南通常也会出现在一方或另一方面,但在这方面相当灵活。
我的问题是,鉴于这种高度的灵活性,使用一致的风格有多重要?例如,假设作者写了类似
的内容using std::vector;
vector<T> v;
std::cout << v[0] << std::endl;
使用std :: vector但不是std :: cout或std :: endl的不一致应用程序通常被认为是可接受的,还是被认为是无纪律的?
答案 0 :(得分:7)
我认为using
的重点在于你在名称中使用它不一致。在某些块中经常需要的名称可以使用using声明在本地声明,而其他块则不是。我没有看到这个问题。
声明具有命名空间范围的名称总是要难得多。我认为如果知道名称明确属于某个特定的命名空间,那么就不会将其与其他命名空间混淆,如果它使代码更具可读性,那么放置using声明也不会有害。
答案 1 :(得分:2)
我现在是明确声明命名空间的强烈支持者(即没有'使用')
大多数人的命名空间历史都是这样的(非平凡的,> 100kloc项目)
纯真 - &gt;风格1
using namespace std;
哎哟 - &gt;风格2
using std::string;
using std::vector;
好的,已经够了 - &gt;风格3
std::string foo = "xxx";
答案 2 :(得分:1)
假设您没有在任何地方说using namespace std;
,我认为大多数开发人员并不关心其他人的代码。唯一可能困扰他们的是过度使用std :: qualifier ---如果你在函数中说“std :: vector”20次,也许是时候使用“std :: vector”了。否则,没有人应该关心。
有时候,在我自己的代码中,我将专门使用“std ::”限定符来表明这是我正在使用该
答案 3 :(得分:0)
我尝试使用using
not (没有双关语)。
为了保存输入,我喜欢做typedef,例如:
typedef std::vector< int > IntVector;
typedef std::vector< Foo > FooVector;
答案 4 :(得分:0)
这不是一个答案,而是与一些其他答案相对立,这些答案主张总是明确地将命名空间作为名称的一部分。有时,这是一个糟糕的主意。在某些情况下,您希望使用专门用于手头类型的名称(如果存在),但是否则使用标准提供的替代方案。
作为一个典型的例子,让我们考虑一个排序函数。如果你要对T类型的某些对象进行排序,那么你最终会交换项目。您希望使用特殊swap(T &, T&)
(如果存在),但template <class T> std::swap
。
如果您尝试指定要明确使用的交换的全名,则必须指定其中一个 - 要么指定专用版本,要么对不具有该类型的类型实例化排序定义它自己的交换将失败,或者你指定std::swap
,并忽略专门为你正在排序的类型提供的任何交换。
using
提供了摆脱这种困境的方法:
using namespace std;
template <class T>
mysort(/* ... */ ) {
// ...
if (less(x[a], x[b])
swap(x[a], x[b]);
// ...
}
现在,如果找到T的命名空间包含swap(T &, T&)
,则可以通过参数依赖查找找到它,并在上面使用。如果它不存在,则std::swap
将被找到(并使用),因为using namespace std;
也使其可见。
顺便说一句,我认为通过一个小修改,using namespace x;
几乎可以完全无害。就目前而言,它将该命名空间中的名称引入当前范围。如果其中一个恰好与当前范围中存在的名称相同,则会发生冲突。当然,问题在于我们可能不知道命名空间包含的所有内容,因此几乎总是存在至少一些冲突的可能性。
修改是将using namespace x;
视为创建围绕当前范围的范围,并将该命名空间中的名称引入该范围。如果其中一个恰好与当前作用域中引入的名称相同,则不会发生冲突 - 就像任何其他块作用域一样,当前作用域中的名称将隐藏与周围作用域相同的名称。 / p>
我没有仔细考虑过这个问题,所以毫无疑问会有一些需要更多关心才能解决的问题,但我认为一般的想法可能会使很多事情变得更加简单