Search

6.12 — Using declarations and using directives

You’ve probably seen this program in a lot of textbooks and tutorials:

Some older compilers will also start new projects with a similar program.

If you see this, run. Your textbook, tutorial, or compiler are probably out of date. In this lesson, we’ll explore why.

A short history lesson

Back before C++ had support for namespaces, all of the names that are in now in the std namespace were in the global namespace. This caused naming collisions between program identifiers and standard library identifiers. Programs that worked under one version of C++ might have a naming conflict with a newer version of C++.

In 1995, namespaces were standardized, and all of the functionality from the standard library was moved out of the global namespace and into namespace std. This change broke older code that was still using names without std::.

As anyone who has worked on a large codebase knows, any change to a codebase (no matter how trivial) risks breaking the program. Updating every name that was now moved into the std namespace to use the std:: prefix was a massive risk. A solution was requested.

Fast forward to today -- if you’re using the standard library a lot, typing std:: before everything you use from the standard library can become repetitive, and in some cases, can make your code harder to read.

C++ provides some solutions to both of these problems, in the form of using statements.

But first, let’s define two terms.

Qualified and unqualified names

A name can be either qualified or unqualified.

A qualified name is a name that includes an associated scope. Most often, names are qualified with a namespace using the scope resolution operator (::). For example:

For advanced readers

A name can also be qualified by a class name using the scope resolution operator (::), or by a class object using the member selection operators (. or ->). For example:

An unqualified name is a name that does not include a scoping qualifier. For example, cout and x are unqualified names, as they do not include an associated scope.

Using declarations

One way to reduce the repetition of typing std:: over and over is to utilize a using declaration statement. A using declaration allows us to use an unqualified name (with no scope) as an alias for a qualified name.

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

The using declaration 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 (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).

Using directives

Another way to simplify things is to use a using directive. A using directive imports all of the identifiers from a namespace into the scope of the using directive.

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

The using directive using namespace std; tells the compiler to import all of the names from the std namespace into the current scope (in this case, of function main()). When we then use unqualified identifier cout, it will resolve to the imported std::cout.

Using directives are the solution that was provided for old pre-namespace codebases that used unqualified names for standard library functionality. Rather than having to manually update every unqualified name to a qualified name (which was risky), a single using directive (of using namespace std;) could be placed at the top of the each file, and all of the names that had been moved to the std namespace could still be used unqualified.

Problems with using directives

However, for modern C++ code, using directives offer little benefit (saving some typing) compared to the risk.

Because using directives import all of the names from a namespace (potentially including lots of names you’ll never use), the possibility for naming collisions to occur increases significantly (especially if you import the std namespace).

For illustrative purposes, let’s take a look at an example where using directives 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, employing a using declaration instead, or qualifying x with an explicit scope qualifier (a:: or b::).

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.

Even if a using directive does not cause naming collisions today, they make code more vulnerable to future collisions. For example, if your code includes a using directive for some library that is then updated, all of the new names introduced in the updated library are now candidates for naming collisions with your existing code.

There is a more insidious problem that can occur as well. The updated library may introduce a function that not only has the same name, but is actually a better match for some function call. In such a case, the compiler may decide to prefer the new function instead, and the behavior of your program will change unexpectedly.

Consider the following program:

foolib.h:

main.cpp:

This program runs and prints 1.

Now, let’s say we update the foolib library, which includes an updated foolib.h. Our program now looks like this:

foolib.h:

main.cpp:

Our main.cpp file hasn’t changed at all, but this program now runs and prints 2!

When the compiler encounters a function call, it has to determine what function definition it should match the function call with. In selecting a function from a set of potentially matching functions, it will prefer a function that requires no argument conversions over a function that requires argument conversions. Because the literal 0 is an integer, C++ will prefer to match someFcn(0) with the newly introduced someFcn(int) (no conversions) over someFcn(double) (requires a conversion from int to double). That causes an unexpected change to our program results.

This would not have happened if we’d used a using declaration or explicit scope qualifier.

The scope of using declarations and directives

If a using declaration or using directive is used within a block, the names are applicable to just that block (it follows normal block scoping rules). This is a good thing, as it reduces the chances for naming collisions to occur to just within that block.

If a using declaration or using directive is used in the global namespace, the names are applicable to the the entire rest of the file (they have file 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.

Best practices for using statements

Modern C++ doesn’t really have a place for using directives. They increase the chance for naming collisions now and in the future, and can cause more insidious problems. Although many textbooks and tutorials use them liberally, using directives are best avoided altogether.

Using declarations are generally considered safe to use inside blocks. Limit their use in the global namespace of a code file, and never use them in the global namespace of a header file.

Best practice

Prefer explicit namespaces over using statements. Avoid using directives altogether. Using declarations are okay to use inside blocks.

Related content

The using keyword is also used to define type aliases, which are unrelated to using statements. We cover type aliases in lesson 8.6 -- Typedefs and type aliases.


6.13 -- Unnamed and inline namespaces
Index
6.11 -- Scope, duration, and linkage summary

135 comments to 6.12 — Using declarations and using directives

  • ShayYin

    "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."

    Why it will output an error? wasn't it stated that std::cout would be preferred in cases like this? if there's a naming collision?

    • Alex

      No, std::cout would be preferred if we had a using declaration such as "using std::cout".

      In this case, we're using a using directive, which doesn't have a priority.

  • "We could resolve ... using statements, using a using declaration instead ...".

    I think the above sentence can be made cleaner and easier to read by replace the 'using' after the comma with 'through the use of a' or 'by substituting it with'  or 'by employing'.    

    There are far too many 'using's in a span of 5 words that it becomes really confusing to the reader.

  • Jake

    At last I can now comment and help
    thanks as always

  • Waldo Lemmer

    Section "Qualified and unqualified names":

    > An unqualified name is a name that does not include a scoping qualifier. For example, cout and x are an unqualified names,

    The "an" shouldn't be there.

    Section "The scope of using declarations and directives":

    > If a using declaration or using directive is used within a block, the names are applicable to just 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.

    I think this should be "to just within that block."?

    Everywhere:

    The namespace identifiers start with capital letters.

  • James C

    In this paragraph

    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, using a using directive instead, or qualifying x with an explicit scope qualifier (a:: or b::).

    I think you meant to say "using a using declaration" instead of 'directive'. I might be wrong, though.

  • Chayim

    In this code mentioned above:

    How is it able to print out both 'cout's the std and the int? The std with a prefix std::cout <<"Hello,world!" and how do we print out the cout function alongside with the std cout?

  • Waldo Lemmer

    1. Question:
    Why is

    called a "using directive", and

    called a "using declaration"? Knowing why would help me to remember which is which.

    2. I want to keep using std::cin and std::cout, because:
    - It's not that inconvenient
    - It increases readability (imo) because the `std::` prefix helps me to distinguish between `cout` and other similar-looking four-letter keywords and identifiers.
    - I don't have to worry about keeping using declarations out of the global scope
    - I'm already used to typing `std::cin` and `std::cout`

    3. This lesson is marked as "Updated", despite being last edited half a year ago. Not sure if it's intentional, just wanted to point that out.

    4. Tiny correction:
    Section "The using directive", after the second snippet:

    > one of the `using statements`, or using
    "statements" should not be monospaced.

    (I'm afraid that I might be annoying you/wasting your time by pointing these small errors out, please let me know if this is the case :))

  • alsaht

    first thanks for the great tutorials
    second while i was trying , i noticed that using directives within a block or in global scope they move all identifiers from a namespace (like std) to the global namespace (until the block ends)

    and
    when i try this i get a compile error
    {
    int cout = 5;
    using std::cout; // redeclaration error !!

    }

    so using declarations in a block move an identifer from the namespace to the block (until the block ends)
    am i right ?

  • Alexander

    I have a very important question to ask , as I've been following the site for more than half a year though I had taken some breaks I just stumbled upon a book named "Begining C++ through Game programming by Michael Dawson".
    I wanted to ask you about the book, and I'm a little doubtful only because the author uses using directive statement "using namespace std" in the global namespace so do you think I should follow the book I mean it's Content is good to apply my knowledge of C++ in practice . Please answer

  • choofe

    Hi
    I had a post here that I used size_t in my code. nascardriver suggested to change them to std::size_t.
    I asked the difference and answer was "- `size_t` is C, `std::size_t` is C++."
    Now I'm wondering that there are both int_fast32_t and std::int_fast32_t. While I'm using

    and there is

    which data type compiler will choose?
    At runtime compiler shows int for both

    I noticed there are some functions which have the same name like exp ,log ,pow ... what about those?

    • nascardriver

      C++ defines them in the `std` namespace, but requires that the headers are the same as the C headers (eg. <cmath> is the same as &;tmath.h>) (Which don't have namespaces), with some exceptions. The `std` versions might be aliases, or overloads that don't exist in C.

      So when you use `std::int_fast32_t`, that's probably an alias for `int_fast32_t`.

  • While inside a using statement, is it possible to use the scope resolution operator (::) to get outside of the using statement? e.g.,

    • Wait, the example I gave just won't work, because it's ambiguous.
      How about this instead:

      • Okay I figured some stuff out: using declarations seem to only change that one specific instance; i.e., in the code below, "using foo::printNamespace" only changes 'printNamespace' to 'foo::printNamespace', but '::printNamespace', 'goo::printNamespace', etc., aren't 'prefixed' with 'foo::', but instead just stay the same.
        Also interesting is how prefixing with just '::' doesn't really affect it. My guess is that it looks for the namespace inside the global namespace, so it just ends up being the same as looking for the namespace by itself; i.e., "::goo::printNamespace()" looks in the global namespace for 'namespace goo', and then looks inside 'namespace goo' for 'printNamespace()'.

  • samosamo

    when i try to declare local variable in function main and use using declaration it makes a compile error
    why ?
    here is my code :

    #include <iostream>
    using namespace std;
    namespace math{
        int add(int x , int y){
           cout << "hello from namespace math" << endl ;
            return x + y;
        }
        int mul(int x , int y){
            return x * y;
        }
        int sub(int x , int y){
            return x - y;
        }
        int divi(int x , int y){
            return x / y;
        }

    }

    int add(int x , int y){
           cout << "hello from global namespace" << endl ;
           return x + y;
    }

    int main()
    {
        int add = 5;
        using math::add;
        cout << add(5,5);
        return 0;
    }

    • Braithiar

      The variable you named add (int add = 5;) is conflicting with the functions you also named add(). If you changed the name of int add, or comment it out, your program will compile.

  • Gowtham

    I think even after the using declaration "using std::cout", the compiler still can have some difficulty referencing 'cout' to either 'std' or the function 'cout()'. Because when the compiler reaches to 'cout', how can it decide which one to use while there are still two declarations for 'cout' ?

    >or used a using declaration instead of a using directive:

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

    • I think [but am not entirely sure] that

      makes each mention of 'cout' become 'std::cout'. Therefore, it won't confuse the two: each mention of 'cout' would never refer to the function 'cout()', but rather 'std::cout'.

  • sami

    > The using declaration of using std::cout;
    At first it was confusing, the I thought maybe the following could help to be less vague:

    The using-declaration of using std::cout;

    > The using directive using namespace std;
    'of' is missing and how about?

    The using-directive of using namespace std;

  • sami

    > If there’s a naming conflict between std::cout and some other use of cout, std::cout will be preferred.

    What is the reason behind this?

    Can you give an example?

    can we change the code to use 'cout' from our user-defined namespace instead of std namespace?

  • JasonA

    The statement:

    “The using declaration using std::cout; tells ...”

    Is not as clear to read as it might be, because of the formatting that you’ve chosen.  The font for “using declaration using std::cout;” appears (at least on my iPad running Chrome) to be same for all the words.  You really have two things, ie, a “using” declaration, and the actual usage in the code “using std::cout;”.  It seems like there should be a different formatting for both. I understand that the keyword “using” should be highlighted, but then “declaration” should just be the same ordinary body text. And then the code itself needs its own highlighting.

    Does this make sense ? When I read this, on first glance, I thought that the actual line of code was “using declaration using std::cout;”, and I was then doing a double-take because I hadn’t heard of that before.  And then the penny dropped !

    • Alex

      Totally makes sense. I stuck a word in between the two identically formatted terms to offset them a bit and improve readability. Thanks!

  • Josh

    "Rule: Avoid “using” statements outside of a function (in the global scope)."

    and

    "Suggestion: We recommend you avoid “using directives” entirely."

    aren't in those nice colorful windows.

  • Charan

    Hey,
    So, the conflict in the more subtle example occurs because the global namespace is declared by default by our program(or compiler?who does that by the way?) ,isn't it?As if the compiler has to look into both name spaces.  I don't know if it's the case but isn't it more 'tactical' if the compiler looks into the std namespace first and then into the global namespace?

    • Forhad Rahman

      Why will you check in another folder if you find you file in the first place? Also, why will you check another folder if you don't find your file first? [There are many people out there who easily give up]

      It's the way the compiler has been made. They won't look into another library if they don't find it first. Imagine there are 100 of library, and the 100th library is containing the target file, now the compiler have to look in all of them! It'll cost a lot of time and memory.

      It's better to stay alerted first :v

  • Arionne Coleman

    I thought you needed parenthesis to call a function, why would cout confuse the compiler instead of recognizing that it is using the std namespace and not the user-defined function?

  • Red Lightning

    The stupidest thing I can think of is a programmer making a namespace, and then putting a "using directive" in the global scope of his program, which results in the same chances for naming collisions as if he didn't even make the namespace.

    Compiling...and...error.

  • Now the syntax of using "using" in a scope block is a bit confusing to me.
    Maybe also because the closest Pascal variant I ever saw is more logical:

    Thanks to 'width' the h1 and h2 are part of x.... Now the "using" variant C++ offers wants it INSIDE the block....

    In stead of:

    I guess enabling "using" in the global scope could be the most logical explanation for this (which "if" or "while" can't do), but still it baffles me... This syntax could haunt me, hahaha ;)

    Now I wonder....

    • Namespace members can access other members of the same namespace without "jeroen::".

    • Alex

      Pascal's "with/do" is designed to allow you to quickly access the fields/members of a given record/struct.

      C++'s "using" is designed to provide access to all declarations and definitions within a given namespace without the namespace qualifier.

      Totally different uses, hence, different syntaxes.

  • Jules

    In this example :

    include <iostream> // imports the declaration of std::cout

    int cout() // declares our own "cout" function
    {
        return 5;
    }

    int main()
    {
        using namespace std; // makes std::cout accessible as "cout"
        cout << "Hello, world!"; // uh oh!  Which cout do we want here?  The one in the std namespace or the one we defined above?

        return 0;
    }

    How can you call a function (cout, the user defined one) without its arguments?, in this case empty ().
    Woudnt the compiler throw an error at you?

    • Hi Jules!

      The compiler will error out. It doesn't check the types of @cout and @std::cout. It notices that there are 2 functions/variables with the same name and stops.
      If you were to remove the "using namespace std;" line, there'd still be an error (Because cout is missing "()")

  • Benur21

    Please, can you put all "using" words that you mean the "using" statement between quotes (or italics)? I couldn't understand a few sentences in the first place because of this.

    PS: Or if you mean "using" not as a statement, but as a "using declaration", for example, put them also between quotes. (look at the titles)

  • Suprith

    #include <iostream> // imports the declaration of std::cout

    int cout() // declares our own "cout" function
    {
        return 5;
    }

    int main()
    {
        using namespace std; // makes std::cout accessible as "cout"
        cout << "Hello, world!"; // uh oh!  Which cout do we want here?  The one in the std namespace or the one we defined above?

        return 0;
    }
    My doubt is , in the above example, cout should suppose to resolve to std:cout. Why it'll conflict with int cout().

    • Alex

      Nope. using namespace std tells the compiler "std::cout" should be referenceable as "cout". Thus, when we call "cout", the compiler doesn't know whether we mean std::cout or our own cout function.

      If you want std::cout to take precedence over our own cout inside this function, you should use a using declaration (e.g. using std::cout). Then when the compiler sees cout, it will know that std::cout should take precedence.

      In other words, using declarations (e.g. using std::cout) imply a precedence, using directives (e.g. using namespace std) do not.

      • Suprith

        Thank you so much.

      • saj

        If using std::cout imply a precedence, How will I refer to my own cout() function?
        With a global scope operator :: ?
        And what if my cout() is declared in another .cpp file

        • Alex

          Yes, you can use namespace::cout() where namespace is whatever namespace your cout is in, or ::cout() if your cout is in the global namespace.

          It doesn't matter if it's in another file, as long as the current use can see the forward declaration.

  • why

    HII ALEX ,MY doubt is here "cout" means that is in iostream where cout() this is another function .so it wont give compile error.
    #include <iostream> // imports the declaration of std::cout

    int cout() // declares our own "cout" function
    {
        return 5;
    }

    int main()
    {
        using namespace std; // makes std::cout accessible as "cout"
        cout << "Hello, world!"; // uh oh!  Which cout do we want here?  The one in the std namespace or the one we defined above?

        return 0;
    }

    • nascardriver

      Hi why!

      Just try to compile it yourself, it doesn't work. Don't use 'using namespace' and give your functions unique names and you'll be fine.

  • Q

    Hi Alex,

    In the most recent version of Code::Blocks (17.12), the statement using namespace std is standard for every new file or project you create.
    If it really is such bad practice to use a using directive statement with global scope, then why would a IDE like Code::Blocks implement it in its standard template (with global scope)?
    Wouldn't it suffice if I refrain from naming any of my objects after anything in the std library?
    Below an example of the standard piece of code you get every time you create a project:

    On a unrelated note, thanks for the tutorial. It really is one of the best ones out there.
    Cheers.

    • nascardriver

      Hi Q!

      > why would a IDE like Code::Blocks implement it in its standard template (with global scope)?
      I don't know. A lot of IDEs do this. You can change the new project template in Code::Blocks to your liking.

      > Wouldn't it suffice if I refrain from naming any of my objects after anything in the std library?
      You should definitely do this. But how do you know none of the other code you're using was written with naming conflicts in mind? eg. min and max are common names that cause conflicts from time to time.

      • Q

        Hello nascardriver!

        > But how do you know none of the other code you're using was written with naming conflicts in mind? eg. min and max are common names that cause conflicts from time to time.
        This is a very good point, did not think of this.
        I will just use the scope resolution operator or use a using namespace std in block scope if it makes the code more readable.

        Thank you for replying so fast!

        • Alex

          A few thoughts here:
          1) Yes, it really is bad practice to use "using namespace std" in the global scope (it's more okay at function scope if used judiciously, but personally I avoid it altogether). I'm surprised Code::Blocks does this by default, and I'm not sure what the rationale for doing so would be.

          2) While your code might not have a naming conflict now, you can't guarantee it won't with future extensions of the language! So code that compiles today might not compile once you've upgraded your compiler. Using the explicit qualifier avoids these kinds of issues.

          • Q

            Thank you for your reply and clearing this up, no idea why C::B would do this by default either. I'll just be using std:: from now on. Thanks :)

Leave a Comment

Put all code inside code tags: [code]your code here[/code]