- Learn C++ - https://www.learncpp.com -

6.12 — Using statements

If you’re using the standard library a lot, typing std:: before everything you use from the standard library can become repetitive. C++ provides some alternatives to simplify things, called using statements.

Using declarations

One way to simplify things is to utilize a using declaration statement.

Here’s our Hello world program, with a using declaration on line 5:

The using declaration of using std::cout; tells the compiler that we’re going to be using the object cout from the std namespace. So whenever it sees cout, it will assume that we mean std::cout. If there’s a naming conflict between std::cout and some other use of cout, std::cout will be preferred. Therefore on line 6, we can type cout instead of std::cout.

This doesn’t save much effort in this trivial example, but if you are using cout many times inside of a function, a using declaration can make your code more readable. Note that you will need a separate using declaration for each name you use (e.g. one for std::cout, one for std::cin, etc…).

Although this method is less explicit than using the std:: prefix, it’s generally considered safe and acceptable (when used inside a function).

The using directive

Another way to simplify things is to use a using directive statement. Here’s our Hello world program again, with a using directive on line 5:

The using directive using namespace std; tells the compiler that we want to use everything in the std namespace, so if the compiler finds a name it doesn’t recognize, it will check the std namespace. Consequently, when the compiler encounters cout (which it won’t recognize), it’ll look in the std namespace and find it there. If there’s a naming conflict between std::cout and some other use of cout, the compiler will flag it as an error (rather than preferring one instance over the other).

For illustrative purposes, let’s take a look at an example where a using directive causes ambiguity:

In the above example, the compiler is unable to determine whether the x in main refers to a::x or b::x. In this case, it will fail to compile with an “ambiguous symbol” error. We could resolve this by removing one of the using statements, or using an explicit a:: or b:: prefix with variable x.

Here’s another more subtle example:

In the above example, the compiler is unable to determine whether our use of cout means std::cout or the cout function we’ve defined, and again will fail to compile with an “ambiguous symbol” error. Although this example is trivial, if we had explicitly prefixed std::cout like this:

or used a using declaration instead of a using directive:

then our program wouldn’t have any issues in the first place.

Limiting the scope of using declarations and directives

If a using declaration or using directive is used within a block, the using statement applies only within that block (it follows normal block scoping rules). This is a good thing, as it reduces the chances for naming collisions to occur just within that block. However, many new programmers put using directives into the global scope. This pulls all of the names from the namespace directly into the global scope, greatly increasing the chance for naming collisions to occur (see lesson 2.9 -- Naming collisions and an introduction to namespaces [1] for more information on this).

Best practice

Although many textbooks and tutorials use them liberally, avoid using directives altogether. Using declarations are okay to use inside blocks, where their impact is limited, but not in the global scope.

Cancelling or replacing a using statement

Once a using statement has been declared, there’s no way to cancel or replace it with a different using statement within the scope in which it was declared.

The best you can do is intentionally limit the scope of the using statement from the outset using the block scoping rules.

Of course, all of this headache can be avoided by explicitly using the scope resolution operator (::) in the first place.


6.13 -- Typedefs and type aliases [2]
Index [3]
6.11 -- Scope, duration, and linkage summary [4]