简体   繁体   English

使用“std”的标准惯例

[英]Standard convention for using “std”

Exact Duplicate: Do you prefer explicit namespaces or 'using' in C++? 完全重复: 您更喜欢C ++中的显式名称空间还是“使用”?

Which of these is a preferred convention for using any namespace? 以下哪一项是使用任何命名空间的首选约定?

using namespace std;

or 要么

using std::cin;
using std::cout;

or 要么

calling the function as and when required in the code? 在代码中需要时调用函数?

std::cout<<"Hello World!"<<std::endl;

A very good explanation is given here . 这里给出一个非常好的解释。

The first style ie using namespace whatever defeats the whole purpose of namespacing. 第一种风格,即使用命名空间,无论如何都会破坏命名空间的整个目的。 You should never be using it except in small code snippets. 除了小代码片段之外,你永远不应该使用它。 (I don't use it there either! :D ) (我也不在那里使用它!:D)

Second one is way too verbose. 第二个是太冗长了。 Not practical. 不实用。

I personally like the third style ie typing out the fully qualified name (eg std::cout). 我个人喜欢第三种风格,即输入完全限定名称(例如std :: cout)。

Remember, the code is read much more times than it is written & using fully qualified names IMO makes your code more readable. 请记住,代码的读取次数比使用完全限定的名称读取的次数多得多,IMO使代码更具可读性。

This has been asked many times before, but my SO search fu seems to have deserted me for the moment. 之前已经多次询问过,但我的SO搜索似乎暂时抛弃了我。 Basically: 基本上:

  • Never put a using directive of any sort in a header file – doing so will contaminate your code and introduce all sorts of hard to track down bugs. 永远不要在头文件中放置任何类型的using指令 - 这样做会污染您的代码并引入各种难以追踪的错误。

  • Prefer a using declaration, like using std::string , in an implementation (.cpp) file that makes heavy use of such a type. 首选使用声明,例如在强制使用此类型的实现(.cpp)文件中using std::string

  • As a last resort, use using namespace std , but only in implementation files – I use it in posts of compilable code on SO, for convenience. 作为最后的手段,使用using namespace std ,但只在实现文件中使用 - 为方便起见,我在SO的可编译代码帖子中使用它。

This is a modified version of another answer I wrote on the same subject. 这是我在同一主题上写的另一个答案的修改版本。 Enough of these questions and maybe I will end up with a definitive post ;) 足够这些问题,也许我最终会得到一个明确的帖子;)

The major issue is name conflicts, in that if you have a variable called cout in your code and you are using namespace std; 主要问题是名称冲突,因为如果您的代码中有一个名为cout的变量,并且您正在using namespace std; it will be ambiguous as to what you mean. 你的意思是模棱两可的。 It isn't just cout . 这不仅仅是cout count , reverse and equal will also be included, which are all common identifiers. countreverseequal也将被包括在内,它们都是常见的标识符。

Disregarding all problems to the compiler, it is also a problem for anyone coming to read your code. 无视编译器的所有问题,任何人来阅读您的代码也是一个问题。 Those extra 5 characters ensure that the next person maintaining your code knowns exactly what you mean. 这些额外的5个字符可确保维护代码的下一个人确切知道您的意思。


It is also worth noting that you should never put 值得注意的是,你永远不应该放

using namespace std;

In a header file, as it can propagate to all files that include that header file, even if they don't want to use that namespace. 在头文件中,因为它可以传播到包含该头文件的所有文件,即使他们不想使用该命名空间。 Another problem here is that it is also not clear that the std namespace has been imported, so the maintainer (or you in 3 months time) adds a variable with the same name as some obscure std function that was included into the same compilation unit and then spends an hour trying to find the cause of the compilation error. 这里的另一个问题是,还不清楚std命名空间是否已被导入,因此维护者(或者你在3个月的时间内)添加一个变量,其名称与包含在同一编译单元中的一些不起眼的std函数相同。然后花费一个小时试图找到编译错误的原因。

In the majority of cases it is very beneficial to use things like 在大多数情况下,使用像这样的东西是非常有益的

using std::swap

As if there is a specialized version of swap, the compiler will use that, otherwise it will fall back on std::swap . 好像有一个专门的swap版本,编译器将使用它,否则它将回退到std::swap If you call std::swap , you always use the basic version, which will not call the specialized version (even if it exists). 如果你调用std::swap ,你总是使用基本版本,它不会调用专用版本(即使它存在)。

Take for example code using the pimpl idiom . pimpl成语为例。 Where as the default copy may copy all the data in the actual implementation, where as all that needs doing is swapping the pointers. 默认副本可以复制实际实现中的所有数据,其中所有需要做的就是交换指针。 Using a specialized swap could save huge amounts of execution time, and well designed libraries should specialize it. 使用专门的交换可以节省大量的执行时间,精心设计的库应该专门化它。


In summary, 综上所述,

  • Always prefer using std::swap over std::swap() 总是喜欢在std::swap() using std::swap

  • Avoid using namespace std in a header at all costs due to propagation, try to avoid using it in implementation files. 由于传播,不惜一切代价避免在头文件中using namespace std ,尽量避免在实现文件中使用它。

  • Having thousands of using std::foo at the top of every file is not the way to go. 在每个文件的顶部using std::foo数千个using std::foo是不可取的。 At most use it for commonly use classes. 最多使用它用于常用类。

Everything else is opinion. 其他一切都是意见。

I personally prefer the third option. 我个人更喜欢第三种选择。 Just have a look at this: 看看这个:

namespace A { int a=0; }
namespace B { int a=0; }

and you use it as: 你用它作为:

using namespace A;
using namespace B;
using namespace std;

cout<<a<<endl; //error here!

Instead if you could just say, 相反,如果你可以说,

std::cout<<B::a<<std::endl; //No problem, more readable

Although it might take a bit more time to type the code out, the second and the third options are more (kind of) preferred. 尽管输入代码可能需要更多时间,但第二个和第三个选项更适合(有点)。

It is a matter of style, but for one thing: You should never import a namespace into the global scope. 这是一个风格问题,但有一点:您永远不应该将命名空间导入全局范围。 eg: 例如:

#include <iostream>
using namespace std; // Pollution!

int main()
{
    ....
}

If you want to import the namespace just import it to the scope where you are working: 如果要导入命名空间,只需将其导入到您正在工作的范围:

#include <iostream>

int main()
{
    using namespace std; // Good!
    ....
}

I'd just like to point out that using namespace foo is scoped. 我只想指出using namespace foo是作用域。 Example: 例:

#include <iostream>
#include <vector>
//...
for (int i=0; i<10; ++i)
{
    using namespace std;
    cout << i << endl;
}
vector v; // won't compile

When used with care, using namespace std can be useful and harmless at the same time. 小心using namespace std时, using namespace std可以同时有用且无害。

I always list out the full namespace. 我总是列出完整的命名空间。 It improves readability and lets other people know where your functions and data are coming from. 它提高了可读性,让其他人知道您的功能和数据来自哪里。 using is very annoying when reading other peoples' code, especially when I'm trying to learn something, because I can't tell if it's part of that namespace or the other. 在阅读其他人的代码时using是非常烦人的,特别是当我试图学习某些东西时,因为我无法判断它是否是该命名空间或其他命名空间的一部分。 And like these other sensible people are saying, it does defeat the whole point of namespacing, doesn't it? 就像其他明智的人所说的那样,它确实击败了命名空间的全部意义,不是吗? The point is to keep everything separate and give meaning to the data and logic. 关键是要将所有内容分开,并为数据和逻辑赋予意义。

A good order to remember: the most important person is the client who uses the program; 一个很好的记忆:最重要的人是使用该程序的客户; second most important is other coders who are either maintaining or trying to learn from your code; 第二个最重要的是其他程序员要么维护要么试图从你的代码中学习; least important is you. 最重要的是你。 :-) :-)

It's one thing to recommend writing out the fully qualified name when the namespace is std, where std:: only adds 5 extra characters. 建议在命名空间为std时写出完全限定名称是一回事,其中std :: only只添加5个额外字符。 It's a whole 'nother issue when namespaces stack, and you are faced with writing something like: 当名称空间堆栈时,这是一个完整的“问题”,而且您面临着类似以下内容的问题:

if (NumberOfInstances > 0 && (code_type == MyNamespace::MyLongButMeaningfulClassName::EnumDefinedWithinClass::CODE_GREEN ||
                              code_type == MyNamespace::MyLongButMeaningfulClassName::EnumDefinedWithinClass::CODE_YELLOW)) {

especially if you have a company style guidline limiting lines to 80 characters and you add a few more indents. 特别是如果你有一个公司风格的guidline限制行到80个字符,你又添加了几个缩进。 Something like that obscures the logic of the code behind all the verbiage. 像这样的东西掩盖了所有措辞背后的代码逻辑。 At that point, you start to appreciate using and/or local namespace aliases, in the interest of readability. 此时,为了便于阅读,您开始欣赏使用和/或本地命名空间别名。

Whatever you prefer. 无论你喜欢什么。 Really, it doesn't matter. 真的,没关系。 However, most code-snippets use 但是,大多数代码片段都使用

using namespace std;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM