Don't use using namespace

Each programming tutorial starts with the famous “Hello World!” example. If you type “c++ hello world” into Google you will probably find something like the following code:

#include <iostream>

using namespace std;

int main()
{
    cout << "Hello, World!" << endl;
    return 0;
}

If we declare using namespace some_namespace; we can use functions, classes, and objects from the some_namespace namespace without specifying some_namespace:: before a name. However, this means that we can’t use the same name for our class or function. Even worse, if we import two namespaces and both of them happen to contain a function or a type with the same name the use of that name is ambiguous and we need to disambiguate it by using the namespace prefix anyway otherwise we will get a compile error. This is especially dangerous if we use the using declaration in a header file. Even when everything is working now the ambiguity might arise in the future when we include new code into our project or when somebody includes the header in his project. Last but not least, (this is more of an opinion) the code looks less C++-ish without namespace prefixes. If we look at any serious C++ codebase, the code will probably contain the namespace prefixes. It makes a code more readable since we immediately see where a given class or function comes from.

In general, the advice is to use the namespace prefix. However, there are some namespaces such as std::filesystem::, std::literals::string_literals or std::ranges::views that have quite a long name. If we use them a lot some lines might get unnecessarily long. In that case, we have a couple of options. The first one is the using declaration that allows us to import only a single name from a namespace. In the following example, we import the name of the std::filesystem::path class so that we can use it in the function declaration without specifying the namespace:

#include <filesystem>
#include <string>

using std::filesystem::path;

std::string read_file(path filePath);

The second option (better, in my opinion) is to use a namespace alias. It allows us to make a shortcut of a long name and use that shortcut instead of the long name. The following example shows how to use the alias. Notice that we can use it locally in a function scope. This is preferable (because we don’t pollute the global scope) if we don’t need it anywhere else:

void print_numbers(int from, int to)
{
    namespace rs = std::ranges::views;

    for (int n : rs::iota(from, to))
    {
        std::cout << n << '\n';
    }
}

Further reading: