C++ resolving using namespace std problems using modules - c++

As we know, using using namespace std; in header files is banned in all nontrivial projects. I hate this verbosity but understand its rationale behind.
However, I'm wondering if using C++20/23 modules could be a solution to this.
AFAIK declaring using namespace std; in global scope of headers has two biggest problems:
It pollutes the namespace of all users who include the header.
It pollutes the namespace of all identifiers within the header.
Personally I don't think the second problem is that severe, because the affected scope of identifiers is restricted within a single translation unit. So as far as I know the main reason why people are frowned upon is the first one.
And it seems to me that modules can solve the first one, like this:
export module frozenca;
import std.compat;
// ↓ I think this is definitely NOT OK
// export using namespace std;
// I think this is OK as this is not "propagated" outside of the module.
// Am I correct?
using namespace std;
// .. other details ..
I couldn't find any implementation that the code above compiles, so I couldn't test.
Am I correct?

For the factual form of your question, you are correct. using directives declared in a module unit don't get exported to the interface of that unit. Therefore, they and their effects are locally contained within the module TU which declares them. An import will not using namespace anything.
And for what it's worth, you cannot export using namespace at all. That's a compile error.
That having been said, you should be aware that std contains a lot of names. Many of those names are short, single-word names like begin or sort and the like. Names that you might want to use yourself in certain places.
By bringing in the entirety of std into the local scope, you're opening yourself up to all kinds of potential conflicts.
std:: is just five characters. Get used to them.

Related

Can I use some but not all names from a namespace without having to repeat the full scope for all of them?

Several times in my code I write something like
// all these using
using this::is::a::very::long::name::space::var1;
using this::is::a::very::long::name::space::var2;
using this::is::a::very::long::name::space::var3;
using this::is::a::very::long::name::space::fun1;
using this::is::a::very::long::name::space::fun2;
// to make this line cleaner
fun1(var1,fun2(var2,var3));
because I don't want to make any name from that namespace available, other then the 5 names I've listed.
Does C++ offer anything to use all those names without having to write the common part of the scope over and over?
A key point in your question seems to be that you need to do it often. To alleviate that, you can prime those symbols in a designated namespace.
namespace common_stuff {
// You can also use an alias as the other answer suggests to shorten this
using this::is::a::very::long::name::space::var1;
using this::is::a::very::long::name::space::var2;
using this::is::a::very::long::name::space::var3;
using this::is::a::very::long::name::space::fun1;
using this::is::a::very::long::name::space::fun2;
}
A using declaration is a declaration, and so we created a namespace that contains only five declaration for the things you want. Now, in every scope you want those five to be visible for unqualified name lookup, you can simply add
using namespace common_stuff;
And only those five symbols from common_stuff will be made visible.
You could use a namespace alias:
// Create an alias namespace of the long namespace
namespace shorter = this::is::a::very::long::name::space;
using shorter::var1;
using shorter::var2;
using shorter::var3;
using shorter::fun1;
using shorter::fun2;
If you make the alias short enough, you may not even need the using declarations at all. But otherwise there isn't any other convenient way to pull in a small amount of symbols from a namespace without pulling in everything.
C++ lacks any way to make symbols x,y,z visible from some namespace ns without requiring the repeated using declarations.

multiple "using namespace" in a line?

I searched but I could not find related question.
Please correct me if I'm wrong.
In my project I use the following:
using namespace std;
using namespace sf;
I want it to be like below.
using namespace std, sf;
Thanks in advance!
This syntax is not supported, so you'll have to keep declaring multiple using statements.
In general, though, it's considered best practice to avoid declaring using namespace at all - definitely not in headers, and preferably in the inner-most scope possible (as to not pollute too much scope with unwanted symbols.
I want it to be like below.
using namespace std, sf;
The syntax you're after is simply not supported by the current c++ standard.
Besides it is discouraged to import whole namespaces (at least not in header files), you may sent a request to the c++ standards committee, and see if they like to support that.
The general advice is that you should only
either specify exact classes you're using in your translation unit (to save typing) like using std::cout = co;
or to make everything clear by explicitly using fully qualified identifiers everywhere like std::cout, std::endl, etc.
The latter way is the most readable and best IMO.

Dealing with painfully long namespace names in headers

Is there anything that can be done about looong symbols that need to be referenced in header files, e.g. ABDEFGHIJ::ZXCBVB::AWEDADSDEM::GFGBKGDF::Tools::Item? I know in header files you aren't supposed to using using because it messes up anybody who includes it.
The only working feature that cleans up after itself that I can even think of would be #define+#undef but that seems terrible.
Is there a new feature that solves this that I'm not aware of? I'm also interested in any popular proposals. Maybe using with a bracketed block syntax, to let me restrict the effect to just my header...?
It's not good practice to have a using namespace using directive at global scope in a header file. There are a number of less drastic things you can do that are fairly benign however.
Inside an inline or template function in a header, you can use a using directive without affecting anyone else. This saves you having to qualify all the names in a non-trivial function body.
As Maksim Solovjov suggests, you can use namespace aliases to cut down on typing, with the caveat that a namespace alias at global scope will introduce that alias to anyone including your header so that may not be desirable.
C++11 introduced type aliases and alias templates which can be used in a header at class scope, function scope or namespace scope (you may still want to avoid using them at global scope) to give a shorter name to types. This is particularly useful when dealing with template types with long names like e.g. std::map<std::string, std::vector<std::function<float(float)>>>
C++11 and 14 type deduction through the auto keyword can greatly reduce the need to name long types in headers, whether function return types, local variables or parameters to lambdas.
C++11 decltype can also be useful to avoid saying the names of long types in certain situations.
Here is what I feel.
First of all you should create your own namespaces. Then you can draw in other namespace symbols without polluting the global namespace.
If the namespace you are accessing is truly massive (like std) then I would always either use the std:: qualifier or declare the types explicitly:
namespace my_project {
std::string s; // qualify
// or declare specific types
using std::string;
} // my_project
If the namespace is from your own project or a relatively small library then I see no reason not to inject the whole namespace into your own (never into the global namespace).
namespace my_project {
using namespace xmltools; // never do this in global namespace
// use without prefix here
} // my_project
The key is to use your own namespaces. Then what you do inside them will have less affect on people using your headers.
I think the main point is to remember that if someone injects the symbols from your namespace into their own they should not be surprised by what it contains.
So if my library builds on another library it may be normal for my library to contain the type symbols from the other library and someone injecting my namespace into theirs would also expect that.
You can have namespace aliases:
namespace fbz = foo::bar::baz;
However, you would introduce fbz to every file that includes your header.

c++ namespace best practice dilemma

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.

How to resolve a naming conflict between two libraries in C++?

I am using two large libraries (GUI & network) and I can happily do
using namespace FirstLib;
using namespace SecondLib;
Except for 1 single class called Foobar where names clash.
I my code, I do not use FirstLib::Foobar. Is there a way to say "in my code, whenever you see Foobar, think SecondLib::Foobar ?
using namespace is evil! Namespaces were made to prevent such problems as you have! But that said, try:
using namespace FirstLib;
using namespace SecondLib;
using SecondLib::Foobar;
or even (for some compilers):
using namespace FirstLib;
using namespace SecondLib;
typedef SecondLib::Foobar Foobar;
It's strange nobody suggested to replace the full namespace use by the list of used class names. This solution is even in the C++faq (where I should have thought to look first).
If we cannot say
include all FirstLib, but remove SecondLib::Foobar
We can use using-declarations of the exact elements we need:
using FirstLib::Boids;
using FirstLib::Life;
// no using FirstLib::Foobar...
You've basically answered your own question. You must explicitly say which class you want to use, so you must do SecondLib::Foobar whenever you use that class.
You have to pick one of these namespaces and get rid of the 'using', and explicitly call out all the class names. C# has a way around this, but C++ does not afaik...
I don't think there's a way of excluding names. You either bring in the whole lot, or each one individually. Even when you bring in the whole lot, you can always disambiguate conflicting names by qualifying them fully.
However, you could use typedef to rename the offending class:
typedef Lib2::FooBar FooBaz;
And I guess, with a conflicting function, you could use a function pointer to "rename" the conflicting one.
I guess it's kind of a non-solution. I can understand the occasional motivation to use using declarations - sometimes there are indeed many different names that you'll use all over the place - but if just one is conflicting: be explicit. It would be confusing to anyone familiar with the libraries anyway, seeing that both namespaces are imported.
Also, using declarations respect scope: you can make one namespace visible in one function, but not the other namespace - assuming you don't even use it in that function.
Have you tried:
using SecondLib::Foobar;
?
If you load all elements from both namespace to current scope by use of using namespace directove:
using namespace FirstLib;
using namespace SecondLib;
and there is potential that some of the names in those namespace may clash, then you need to tell compiler explicitly which of the element you want to use, in current scope, by use of using declaration:
using SecondLib::Foobar;
As the C++ standard says:
7.3.3 The using declaration
1 A using-declaration introduces a
name into the declarative region in
which the using-declaration appears.
That name is a synonym for the name of
some entity declared elsewhere.
This line requests compiler to think SecondLib::Foobar whenever it sees Foobar for the rest of current scope in which the using declaration was used.
The using directive and declaration is very helpful, but they may cause problems as the one you're dealing with. So, it's a good idea to narrow use of any form of using to minimal scope possible. You can use the directive using namespace in scope of other namespace
namespace MyApp {
using namespace ::SecondLib;
}
or even a function. The same applies to using declaration. So, it's a good idea to narrow the scope of use of any of them:
void foo()
{
::SecondLib::Foobar fb;
}
It may seem tedious, but it is only when you type, though you most likely use intellisense-enabled editor, so cost is really small, but benefits are large - no confusions, readable code, no compilation issues.
It's also a very good idea to NOT to use using namespace in header scope. See Header files usage - Best practices - C++
My own tip: do use full qualification whenever you need to use any of these types