Summary
In this post, I will introduce how to use "using" in C++, in other words, how to use an existing namespace.
Conclusion
As usual, I present the conclusion first. The followings are recommended ways which minimize name collision possibilities and maximize code clarity and writing convenience.
See this post as well.
For Headers
- Do not put any namespace using statement at the top level in headers;
- Use fully qualified names (for example, std::string for Standard Library names) in headers. Or you can use narrowly-scoped namespace using statements.
For Source Files
- Put namespace using statements in local scopes;
- Do not use fully qualified names everywhere;
- Do not use
using namespace std
, but use specific using declarations for just the names you need (for example,using std::string
andusing std::cin; using std::cout; using std::endl;
);
Details
For Headers
Rule 1: Do not put any namespace using statement at the top level in headers.
Reason: If you do so, when other programmers include your header, they can’t override it with their own, which increases collision possibilities.
Rule 2: Use fully qualified names.
Reason: Based on Rule 1, you have to use fully qualified names in headers.
For Source Files
Rule 1: Put namespace using statements after all "#includes …".
Reason: If you do so, the compliler will put the using namespace std before "onnx_loader.h", which increases collision possibilities.
#include <iostream>
using namespace std;
#include <onnx_loader.h>
#include <iostream>
#include <onnx_loader.h>
// all other #include’s
using namespace std; // no harm done to headers
Rule 2: Do not use fully qualified names everywhere.
Reason: It draws people’s attention to the colon colon and confused people.
// I think most people won't happy to review codes full of stds
std::string foo(std::map<std::string, std::greater<std::string>, std::string>& table) {
std::string s1, s2;
std::cout << “Enter two strings:” << std::endl;
std::cin >> s1 >> s2;
std::map<std::string, std::greater<std::string>, std::string>::iterator it = table.find(s1);
}
Rule 3: Use specific using declarations.
Reason: To solve rule 2, we write clear codes conviniently. We use local using-declarations
instead of global ones.
string foo(map<string, greater<string>, string>& table) {
using std::string;
using std::map;
using std::greater;
using std::cout; using std::endl; using std::cin;// using console I/O in the same line
string s1, s2;
cout << “Enter two strings:” << endl;
cin >> s1 >> s2;
map<string, greater<string>, string>::iterator it = table.find(s1);
}