Search

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 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
Index
6.11 -- Scope, duration, and linkage summary

115 comments to 6.12 — Using statements

  • 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?

  • 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]