115

I'm using the 'using' declaration in C++ to add std::string and std::vector to the local namespace (to save typing unnecessary 'std::'s).

using std::string;
using std::vector;

class Foo { /*...*/ };

What is the scope on this declaration? If I do this in a header, will it inject these 'using' declarations into every cpp file that includes the header?

Jeff Lake
  • 1,769
  • 2
  • 13
  • 9
  • 27
    Just in case it's not clear from the other answers here: - **Do not put a `using` declaration (or `using` directive) at file scope in an include file/header!** That will cause headaches for users of the header. – Michael Burr Oct 21 '08 at 19:07
  • 1
    In fact, do not put a `using` declaration (a fortiori *directive*) in a header **at all**, *even within a namespace!* See [scope of using declaration within a namespace](http://stackoverflow.com/q/6175705/2025416) for problems this causes. – Nils von Barth May 22 '16 at 15:07
  • @NilsvonBarth: That's oversimplified a bit. Using `using` in class and function scope is safe regarding the discussed problem. – Sebastian Mach Oct 17 '18 at 06:45
  • https://en.cppreference.com/w/cpp/language/namespace#Using-directives – Emile Cormier Dec 23 '18 at 19:24
  • You may be interested to read about the [ADL C++ lookup](https://en.cppreference.com/w/cpp/language/adl) _feature_. – Alexis Wilke Aug 05 '19 at 04:44

8 Answers8

134

There's nothing special about header files that would keep the using declaration out. It's a simple text substitution before the compilation even starts.

You can limit a using declaration to a scope:

void myFunction()
{
   using namespace std; // only applies to the function's scope
   vector<int> myVector;
}
Eclipse
  • 44,851
  • 20
  • 112
  • 171
  • 19
    I never thought I could use it inside a function! – Agostino Mar 04 '15 at 22:50
  • 1
    I've got a bunch of namespaces all being used by one "conglomerator"-type file, and gmock unit-testing was extra tedious because each test used things from a specific namespace, and I thought I had to qualify each and every variable. Using `using` inside a function (or even a gtest `TEST` macro!) makes my life so much better! – dwanderson Dec 11 '15 at 16:09
69

When you #include a header file in C++, it places the whole contents of the header file into the spot that you included it in the source file. So including a file that has a using declaration has the exact same effect of placing the using declaration at the top of each file that includes that header file.

Paige Ruten
  • 172,675
  • 36
  • 177
  • 197
  • 60
    ... which is generally a bad thing. – Catskul Feb 16 '11 at 05:25
  • 19
    But if you put the `using` declaration inside a `namespace` it's limited to the scope of that namespace, so is generally OK (with the usual caveats on your particular needs and style). – Zero Dec 04 '12 at 23:09
  • 1
    ...but if you do put using inside a namespace, make sure you aren't doing it to try to get around something that normally is a bad idea, like you can't encase class methods declared outside the namespace Y inside the other namespace X, just so you can locally use the namespace X. Thats why we have use namespace :: resolvers in the first place. If its that big of a problem of typing, either a macro (which can easily lead to code smells) or better yet, isolate it into it's own source .cpp where you will use the namespace there only. – osirisgothra Jan 17 '14 at 17:29
  • 1
    While this and similar answers are good advice, they don't answer the question. – Emile Cormier Dec 23 '18 at 19:20
61

The scope of the using statement depends on where it is located in the code:

  • Placed at the top of a file, it has scope throughout that file.
  • If this is a header file, it will have scope in all files that include that header. In general, this is "not a good idea" as it can have unexpected side effects
  • Otherwise the using statement has scope within the block that contains it from the point it occurs to the end of the block. If it is placed within a method, it will have scope within that method. If it is placed within a class definition it will have scope within that class.
dagorym
  • 5,695
  • 3
  • 25
  • 23
  • 6
    I thought it wasn't possible of adding a `using` statement within class scope... ? I had the same question as the OP because of that as I wanted to avoid typing `std::` all over the place. I got classes that uses a lot of vectors with smart pointers and the five character `std::` prefix adds a lot of line length - which I find reads worse. So I was wondering if a `using` directive within the namespace containing the class was ok? (Even if within a header.) – thomthom Dec 15 '13 at 09:37
  • 9
    What about if it's placed within the scope of a `namespace { ... }`? – einpoklum Nov 20 '15 at 09:09
  • So you can totally write : { using namespace blabla; class blah {}; } and that using will apply only to the class ? – Dinaiz Sep 01 '16 at 09:48
8

The scope is whatever scope the using declaration is in.

If this is global scope, then it will be at global scope. If it is in global scope of a header file, then it will be in the global scope of every source file that includes the header.

So, the general advice is to avoid using declarations in global scope of header files.

JohnMcG
  • 8,709
  • 6
  • 42
  • 49
6

In the case cited, the file ("translation unit"), which means yes, every file that includes it.

You can also put the using statement inside the class, in which case, it's in effect just for that class.

Generally, if you need to specify a namespace in a header, it's often best to just fully-qualify every identifier necessary.

James Curran
  • 101,701
  • 37
  • 181
  • 258
  • Note that the `using` declaration in a class does not behave in the same way as outside a class - eg you can't use it bring `cout` instead of `std::cout` into the scope of the class. – Zero Dec 04 '12 at 23:07
2

That is correct. The scope is the module that uses the using declaration. If any header files that a module includes have using declarations, the scope of those declarations will be that module, as well as any other modules that include the same headers.

Ates Goral
  • 137,716
  • 26
  • 137
  • 190
1

There are a few comments that are rather unqualified when they say "Don't". That is too stern, but you have to understand when it is OK.

Writing using std::string is never OK. Writing using ImplementationDetail::Foo in your own header, when that header declares ImplementationDetail::Foo can be OK, moreso if the using declaration happens in your namespace. E.g.

namespace MyNS {
    namespace ImplementationDetail {
        int Foo;
    }
    using ImplementationDetail::Foo;
}
MSalters
  • 173,980
  • 10
  • 155
  • 350
  • 1
    The user of the header can then write `MyNS::Foo` – Peter Remmers Feb 28 '12 at 13:03
  • A better example is `using boost::posix_time::ptime`. Sure the user could write `MyNS::ptime` but that's not the end of the world, and might be offset by the convenience of being able to have functions like `MyFunction(ptime a, ptime b)`. – Zero Dec 04 '12 at 23:04
  • 5
    *Why* is `using std::string` never ok? Even in your own namespace to save a lot of `std::` prefixes? – thomthom Dec 15 '13 at 09:39
  • @thomthom it is ok when wrapped in a scope such as your own namespace. – jcoffland Nov 17 '16 at 04:43
0

Edited:

As a additional information , put "using" in your source file will affect your header when the statement is placed "before the #include" . ( The scope of using does not extend "backwards" )

header.h

//header.h
#include <string>

std::string t1; // ok
string t2; // ok

header.cpp

//header.cpp
using namespace std ;

#include "header.h"

...
Stardusstt
  • 1
  • 1
  • 1
  • 1
    That should only be the case when the `using` statement is placed before the `#include`: The scope of `using` does not extend "backwards". – Christoph Lipka Jul 15 '21 at 00:12
  • @ChristophLipka So is that a bug by microsoft ? I test it with vscode and visual studio . – Stardusstt Jul 15 '21 at 08:23
  • I can't reproduce your results in VS 2015. If I put `using namespace std;` _before_ `#include "header.h"`. I see VS recognizing `string t2` as `std::string`. However, if I put `using namespace std;` _after_ `#include "header.h"`. I see VS reporting an error on `string t2`. – Christoph Lipka Jul 17 '21 at 14:55
  • Test again , I think that is a bug from intellisense because it can't compile. – Stardusstt Jul 17 '21 at 15:40
  • As an additional note: It is generally expected that header files work "as-is", without requiring any additional statements in the including file. Therefore, writing a header file in such a way that it requires a `using` statement in the including file is usually discouraged. – Christoph Lipka Jul 18 '21 at 06:41