One of the reasons "using namespace" in header files is considered bad practise (Why is "using namespace std;" considered bad practice?) is because it "leaks" the using-directive to everyone that includes your headerfile. Is this still the case for C++ modules or can I "safely" put e.g. using namespace std or using std::cout into my module? :
module;
#include <iostream>
export module Module;
using namespace std;
// using std::cout;
export void greet() {
cout << "Hello World!\n";
}
The scope of any using declaration of this sort is the translation unit being compiled. All module files (a file that starts with some form of module declaration) is a separate translation unit. So it will be just like any other non-exported declaration in your module: local to it.
That having been said, this is only one reason to avoid using namespace std; there are many others. It can play havoc with name lookup. The included names can clash with global names and names used in your namespace. And so forth.
However, employing using declarations for specific components of the std namespace is a lot more reasonable, as the primary reason not to do so is to prevent leakage. Also, namespace aliases are a good idea too, for sub-namespaces like std::chrono, std::filesystem, and the like.
Related
I am trying to understand namespace std. I know what a namespace is. I want to know, is namespace std defined in multiple header files?
I have two sample codes here, and they both compile and run fine. One uses #include<string> and the other uses #include<iostream>. Both use "using namespace std". This tells me that std is defined in both headers, is that right? If so, then when I use both headers in the same code, how will the compiler know which std to use?
CODE 1:
#include <string>
using namespace std;
int main()
{
string test;
test = "hello";
return 0;
}
CODE 2:
#include <iostream>
using namespace std;
int main()
{
string test;
test = "hello";
return 0;
}
A namespace is open; that is, you can add names to it from several separate namespace declarations. For example:
namespace A {
int f();
}
namespace A {
int g();
}
All namespaces with the same name (and in the same scope) are unified to one, so the compiler doesn’t have to choose.
"this tells me that std is defined in both the headers. is that
right?"
The headers include parts of the standard library. Both, iostream and string belong to the standard library, and each of them provides a different set of commands that can be addressed with std::.
The insertion of using namespace resolves the scope, which means that the compiler searches for a function or a command within std::: if it is not found in an inner scope. Therefore, instead of, e.g., writing std::cout << "Hello world" << std::endl; you can simply write cout << "Hello world" << endl; (assuming that iostream is included). This shortens and simplifies the writing of the code, but it can also have disadvantages, which is why using namespace std is generally considered bad practice.
Some headers of the standard library are included indirectly when another header is included. This appears to be the case in your Code2, which compiles although #include<string> is missing.
One cannot rely on such indirect inclusions. More information on this topic can be found here:
Do I have to use #include <string> beside <iostream>?
I know what a namespace is.
Perhaps you do, perhaps not exactly. A namespace is a tool used to prevent naming conflicts. Everything belonging (directly) to a namespace is public, as public identifiers are the only ones that can conflict with code outside the namespace. Unlike a class, there is no encapsulation or data integrity concerns to address; such concerns are relegated to the classes within the namespace.
This open nature of namespaces means that, unlike class definitions, a namespace definition need not be complete. All you need is for (the teams working on) the pieces of the namespace to coordinate their naming schemes. This is why it is typically wrong to add something to someone else's namespace. Since you are not part of the coordination, you could inadvertently introduce a conflict, perhaps quietly introducing undefined behavior, no diagnostic required.
Syntactically, though, you can add to any namespace. This is a useful feature, since traditionally one creates a header file for each class, and namespaces often span more than one class. So it is often desired for a namespace to span multiple header files. How to use namespace across several files? Just use the same namespace name in each namespace definition. A namespace definition is not so much a "definition" as it is a "tour". It is more "this is part of the namespace" than "this is the namespace". The more tours/parts you see, the more complete your view.
On the subject of incomplete views of a namespace, see Can the definition of a namespace span multiple translation units? (Hopefully you guessed "yes".)
I want to know, is namespace std defined in multiple header files?
Yes. The C++ standard dictates dozens of header files that must exist, and implementations are allowed to break those into auxiliary headers. See cppreference.com for a list of the required headers; the ones listed before the "C compatibility headers" section collectively define the std namespace.
Consider this
#include<headerfile1>
#include<headerfile2>
.
.
#include<headerfilen>
using namespace std;
when I write this(header files are all in standard library of C++),does std namespace of all header files come into picture?
Also, if there are two libraries h1 and h2 and both have same namespace x and in those namespaces have same function func(). How do I resolve this?
From cppreference:
A using-directive that names the inline namespace is implicitly
inserted in the enclosing namespace (similar to the implicit
using-directive for the unnamed namespace).
For instance, in the following example, using namespace std::string_literals makes the operator visible inside the scope:
{ // in C++14, std::literals and its member namespaces are inline
using namespace std::string_literals; // makes visible operator""s
// from std::literals::string_literals
auto str = "abc"s;
}
If you use the using directive outside a scope (for instance as in your example), pain will follow, as the commenters stated, especially if this file is a header file: this namespace will be implicitly imported to any file that includes this one. This is why the proper way of managing a big project is to create your own namespace and put all your custom objects in that new namespace. If you really must use a using directive, do so in the implementation file, never in the header, and ideally within scopes.
This will help you avoid most conflicts, unless your namespace uses a common name:
namespace Matrix{ <--- Bad practice, Matrix will probably conflict with something
myStuff ...
}
namespace JohnsAwesomeMatrix236790{ <--- Namespace name is unique,unlikely to get conflicts.
myStuff ...
}
Also, it is much safer to import the few functions that you use instead of the entire namespace:
using namespace std; // Imports the entire namespace!
using std::cout; // Much better, we only import
using std::endl; // the names of the two functions we use a lot
Any decently written library you include will make very careful use of the using directive (if at all), so you normally don't have to worry about this. However, if you use code written with less stringent standards (e.g., scientific code) this is something to look out for.
This question already has answers here:
Why is "using namespace std;" considered bad practice?
(41 answers)
Closed 7 years ago.
Two ways to use the using declaration are
using std::string;
using std::vector;
or
using namespace std;
which way is better?
It depends.
If you want to inject a single name into another scope, the using-declaration is better, e.g.
namespace foolib
{
// allow vector to be used unqualified within foo,
// or used as foo::vector
using std::vector;
vector<int> vec();
template<typename T> struct Bar { T t; };
template<typename T>
void swap(Bar<T>& lhs, Bar<T>& rhs)
{
using std::swap;
// find swap by ADL, otherwise use std::swap
swap(lhs.t, rhs.t);
}
}
But sometimes you just want all names, which is what a using-directive does. That could be used locally in a function, or globally in a source file.
Putting using namespace outside a function body should only be done where you know exactly what's being included so it's safe (i.e. not in a header, where you don't know what's going to be included before or after that header) although many people still frown on this usage (read the answers at Why is "using namespace std" considered bad practice? for details):
#include <vector>
#include <iostream>
#include "foolib.h"
using namespace foo; // only AFTER all headers
Bar<int> b;
A good reason to use a using-directive is where the namespace only contains a small number of names that are kept intentionally segregated, and are designed to be used by using-directive:
#include <string>
// make user-defined literals usable without qualification,
// without bringing in everything else in namespace std.
using namespace std::string_literals;
auto s = "Hello, world!"s;
So there is no single answer that can say one is universally better than the other, they have different uses and each is better in different contexts.
Regarding the first usage of using namespace, the creator of C++, Bjarne Stroustrup, has this to say in §14.2.3 of The C++ Programming Language, 4th Ed (emphasis mine):
Often we like to use every name from a namespace without qualification. That can be achieved by providing a using-declaration for each name from the namespace, but that's tedious and requires extra work each time a new name is added to or removed from the namespace. Alternatively, we can use a using-directive to request that every name from a namespace be accessible in our scope without qualification. [...]
[...] Using a using-directive to make names from a frequently used and well-known library available without qualification is a popular technique for simplifying code. This is the technique used to access standard-library facilities throughout this book. [...]
Within a function, a using-directive can be safely used as a notational convenience, but care should be taken with global using-directives because overuse can lead to exactly the name clashes that namespaces were introduced to avoid. [...]
Consequently, we must be careful with using-directives in the global scope. In particular, don't place a using-directive in the global scope in a header file except in very specialized circumstances (e.g. to aid transition) because you never know where a header might be #included.
To me this seems far better advice than just insisting it is bad and should not be used.
using std::string; and using std::vector;.
Polluting the global namespace with a bunch of symbols is a bad idea. You should just use the std namespace prefix too, so you know that you're using standard library containers. Which is better than both options IMO.
If you are simply using the standard library and nothing else and never will be adding in any other libraries to your project, by all means, use using namespace std; - Whatever you feel more comfortable with in that situation. The convention of "never use using namespace std;" comes from the fact that multiple other libraries define things such as string, vector and such. It is good practice to never import the whole namespace, but it should cause no bothers in your case.
I am writing a small library. Declaration of my classes, functions and others, that uses standard library are in a header file. I know that putting "using namespace" into header is a bad practic. May I put my code in separate namespace and then put "using namespace" into it?
Like this:
// header.h
namespace My
{
using namespace std;
// declarations
}
Will it be good?
Don't do it!
Simply use fully qualified names or using declaration for specific symbols that you want to use.
With this, You will just end up importing the contents of entire std namespace in your namespace My and essentially the header file header.h. Basically, it is going to give you namespace pollution with lot of unused symbols and also increase the compilation time of every translation unit where you include this header.
You may do that but it is not a good idea because this can lead to ambiguious names.
I'm finding that what I've considered "best practice" for use namespace in c++ is hurting the readability of my code, and making me question how to use them well.
My program consists of a few different modules which are mostly built into libraries that the "main" application uses. Each library uses it's own namespace, and their namespaces are all "inside" a project namespace to help project against name conflicts with 3rd party code. So I end up with class names such as "myproject::logging::Logger" and "myproject::reporting::ReportType" (As made up examples).
So far so good. And in my .cpp files I have no problem. I use "using myproject::logging" at the top for example, and can cleanly refer to my Logging class. In the unlikely event of a conflict between two of my namespaces I can just explicitly say which one I want. This works well.
Header files are different though. It's considered bad practice to put using statements into header files as they will affect unrelated code that may not expect them. So I always fully qualify all the names in .hpp files. That was somewhat ugly but managable up to now so I've put up with it. But now I'm increasing using template code in my libraries which means that there is much more actual code in my .hpp files now. And having to fully qualify every name is making the code practically unreadable due to the length of type names.
I'm starting to feel that the benefits of namespaces and best practice for using them are beginning to be outweighed by the unreadablilty of the code I'm having to write. I'm starting to wonder if I would be better abandoning the use of namespaces to gain the benefit of more readable code and fixing any name conflicts if and when they appear.
An alternative is to use short, single layer namespaces so instead of "myproject::logging::Logger" I would merely have "log::Logger" which would help a lot but make the likelyhood of namespace conflicts much higher, and also have the namespaces convey less useful information.
As I've said, this only really affects code in .hpp files as I'm happily using "using namespace" in my implementation files to make this manageable, but it is becoming a problem as I look at my templated code in .hpp files now and think "eww...." which can't be good :P
Anyone got any practical advice?
Here's what I do.
In <mylibrary.h>:
namespace myproject {
namespace mylibrary
{
namespace impl
{
using namespace otherlibrary;
using namespace boost;
using namespace std;
using namespace whatever::floats::your::boat;
class myclass;
class myotherclass;
};
using impl::myclass;
using impl::myotherclass;
};
};
In the source:
#include <mylibrary.h>
using namespace myproject::mylibrary; //clean!
I have been in this situation before. It is often the case that a lot of template functions/classes in your headers are really "implementation", although by the nature of templates in C++ you are forced to put them in a header file. Thus, I just put everything in some "detail" or "implementation" namespace, where I can comfortably use "using namespace". At the end, I "drop" what people should use to the corresponding place. Like this:
namespace myproject { namespace somemodule {
namespace _implementation {
using namespace myproject::othermodule;
using namespace myproject::yetanothermodule;
template <...>
class some_internal_metafunction{
...
};
template <...>
class stuff_people_should_use_outside {
...
};
} // namespace implementation
using stuff_people_should_use_outside ;
}} // namespace myproject::somemodule
This approach might enlarge a bit the names on your compiler reports, though.
Alternatively, you can give up the modules namespaces. But it might not be a good idea for an extremely large project.
Personally? I'd get rid of the "myproject" part. What is the chance that your library will use the exact same namespace name as another and have a symbol defined with the same name as another?
Also, I would suggest shorter names for namespaces you expect to be used in headers.
My experience have been that it is much more convenient to have one namespace for all your code for the reasons you mentioned in your original post. This namespace protects your identifiers from clashing with identifiers from 3rd-party libraries. Your namespace is your dominion and it is easy to keep it name-conflict-free.
I use the following to get rid of enormous amounts of std:: in header file:
// mylibrary.h
namespace myproject {
namespace mylibrary {
namespace impl {
using namespace std;
namespace stripped_std {
// Here goes normal structure of your program:
// classes, nested namespaces etc.
class myclass;
namespace my_inner_namespace {
...
}
} // namespace stripped_std
} // namespace impl
using namespace impl::stripped_std;
} // namespace mylibrary
} namespace myproject
// Usage in .cpp file
#include <mylibrary.h>
using namespace myproject::mylibrary;
It is similar to what was suggested by n.m., but with a modification:
there is one more auxiliary namespace stripped_std.
The overall effect is that line using namespace myproject::mylibrary; allows you to refer to the inner namespace structure, and at the same time it does not bring namespace std into library user's scope.
It's a pity though that the following syntax
using namespace std {
...
}
is not valid in C++ at the time when this post is written.
If your project isn't very very very huge (I mean, very huge), using only myproject should be sufficent. If you really want to divide your project into parts, you can use more generalized namespaces. For example, if I was building a game engine, I would go for namespaces like MyEngine::Core, MyEngine::Renderer, MyEngine::Input, MyEngine::Sound etc.