Namespace and Using

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

  1. Do not put any namespace using statement at the top level in headers;
  2. 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

  1. Put namespace using statements in local scopes;
  2. Do not use fully qualified names everywhere;
  3. Do not use using namespace std, but use specific using declarations for just the names you need (for example, using std::string and using 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);
}

Leave a Reply

Your email address will not be published. Required fields are marked *