Is a using-directive in a detail namespace problematic? - c++

Consider this library header:
#include<vector>
#include<algorithm>
#include<iostream>
namespace Lib {
namespace detail {
using namespace std;
template<class T>
void sort_impl(istream &in,ostream &out) {
vector<T> v;
{
int n;
in >> n;
v.resize(n);
}
for(auto &i : v) cin >> i;
sort(v.begin(),v.end());
for(auto i : v) out << i << endl;
}
}
inline void sort_std() {
detail::sort_impl<int>(std::cin,std::cout);
}
}
Does the detail namespace successfully isolate the clients of the library (and the rest of library's implementation) from the using-directive in this example? I'm not interested in the discussion at Why is "using namespace std" considered bad practice?, even though some of the arguments apply even to "well contained" using-directives.
Note that there are two existing questions concerning the same situation but with using-declarations:
Using declarations in private namespaces in header files
Elegant way to prevent namespace poisoning in C++ (whose one answer is really an answer to the "bad practice" question above)
This could be combined with either of them, but the editing would be severe.

You pollute your own detail namesapce, but not the Lib or global namespaces. So assuming a responsible adult is using your library, they won't have unintentional name collisions:
#include <vector>
namespace Lib {
namespace detail {
using namespace std;
}
}
using namespace Lib;
int main() {
vector<int> v; // This is an error, vector not declared in this scope
}

No, the detail namespace will not isolate clients from the nested using directive. [namespace.udir] is quite explicit about that
A using-directive specifies that the names in the nominated namespace can be used in the scope in which the using-directive appears after the using-directive. During unqualified name lookup, the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace. [ Note: In this context, “contains” means “contains directly or indirectly”. — end note ]
A little example
#include <iostream>
namespace foo {
namespace detail {
using namespace std;
}
}
int main()
{
foo::detail::cout << "Hello World!\n";
// nothing is stopping me from doing that
using namespace foo::detail;
cout << "Hello World!\n";
}
STL gives a nice explanation of how name lookup works in his video Core C++, 1 of n.

Related

Convenient way of 'using namespace' in implementation details (header only library)?

So i work on this library (header only) that has several modules and uses an inline namespace for versioning. Thus the fully qualified names can get a bit longer at times. I would like to use 'using namespace x' as an implementation detail inside the (inline) detail namespaces, but that pollutes the outer namespace.
See the example code on godbolt: https://godbolt.org/z/pdSXrs
I found two workarounds (see godbolt link) that do what I want, but seem to be overly complicated. Is there an easier way to do this? Should I just type out all the fully qualified names (and keep the error messages cleaner)? I would love to know what are the best practices for 'more complicated' namespace constructs.
Edit: added code as suggested
// think of these as in header files
namespace mylib{
namespace module0{
inline namespace mystuff{
// this constant conceptually belongs to module 0 but might be used as an
// implementation detail in other modules
int myconst = 42;
}
}
}
namespace mylib{
namespace module1{
// I would like to use this, but pollutes mylib::module1 namespace
inline namespace detail1{
using namespace mylib::module0::mystuff;
struct foo1{
int operator()(){
return myconst;
}
};
}
}
}
namespace mylib{
namespace module2{
inline namespace detail1{
// this works but seems overly complicated
namespace more_detail{
using namespace mylib::module0::mystuff;
struct foo2{
int operator()(){return myconst;}
};
}
// might be very cumbersome to use if lots of classes
using more_detail::foo2;
}
}
}
namespace mylib{
namespace module3{
inline namespace detail1{
// is this a good way to namespace a library...?
namespace more_detail{
using namespace mylib::module0::mystuff;
// not enough namespaces yet?!
namespace devil_of_details{
struct foo3{
int operator()(){return myconst;}
};
}
}
// useable for lots of classes/types in that namespace... but really?!
using namespace more_detail::devil_of_details;
}
}
}
// think of this as myprogram.cpp including the headers
#include <iostream>
int main(){
// polluted namespace. I can probably live with it, but it's not ideal
// constant should only be visible in module0
int x1 = mylib::module1::myconst;
std::cout << x1 << std::endl;
// ok
int x0 = mylib::module0::myconst;
// this is what I ideally want, i.e. not polluting module2 namespace
int x2_error = mylib::module2::myconst;
// this is what I ideally want, i.e. not polluting module3 namespace
int x3_error = mylib::module3::myconst;
// normal usage in cpp file
using namespace mylib::module2;
int x2 = foo2{}();
std::cout << x2 << std::endl;
// ok
using namespace mylib::module0;
std::cout << myconst << std::endl;
}
I would suggest namespace aliases.
namespace mylib{
namespace module1{
namespace details0 = module0::mystuff;
}
}
While this makes the other namespaces visible, it does not actually import the symbols the way a using does, that is mylib::module1 does not have a myconst member.
Also, note that so long as the namespace you are currently defining is part of mylib, there is no need to have mylib as part of the name. Even if you close mylib then re-open it.
That is:
namespace mylib {
namespace part1 { /* ... */ }
}
namespace mylib {
namespace part2 { namespace p1 = part1; }
}
p1 will refer to mylib::part1 so long as you don't specify that it is a fully-qualified name (::part1).

using "multiple"namespaces one-liner

is there a simplified way to include more namespaces instead of typing every time the same things. This is very annoying, especially in the .h files.
For instance:
Instead of writing:
int f() {
using namespace blabla1;
using namespace blabla2;
using namespace blabla3;
}
I would prefer:
using myNamespace = blabla1, blabla2, blabla3;
int f() {
using namespace myNamespace;
/// this will be equivalent to the previous example
}
Thanks
Using directives are transitive. So if you aggregate them into a single namespace
namespace All {
using namespace A;
using namespace B;
using namespace C;
}
You can then simply do
using namespace All;
And unqualified name lookup will work.
Live example
I'm not sure if this helps you, but if you want to avoid multiple using statements each time, you can wrap the above namespaces, into another namespace:
namespace myNameSpace {
using namespace blabla1;
using namespace blabla2;
using namespace blabla3;
}
and then use it like this:
int f() {
using namespace myNameSpace;
}
Here's a demo.

Using different namespace in same function

Why I get error message (error: call of overloaded myCout() is ambiguous) when I use two different namespaces in same function making use of using namespace directive without fully qualified name space?
#include <iostream>
using namespace std;
namespace first
{
void myCout(void)
{
cout<<"Hello World is great\n";
}
}
namespace second
{
void myCout(void)
{
cout<<"Hello Sky is high\n";
}
}
int main(void)
{
cout<<"Hello World\n";
using namespace first;
myCout();
using namespace second;
myCout();
return(0);
}
If I use fully qualified namespaces for myCout() in second namespace as given below, there is no issue
int main(void)
{
cout<<"Hello World\n";
using namespace first;
myCout();
second::myCout();
return(0);
}
using directives respect scope. So you can introduce a new block scope to limit the availability of the symbols introduced by each:
int main(void)
{
cout<<"Hello World\n";
{
using namespace first;
myCout();
}
{
using namespace second;
myCout();
}
return(0);
}
Normally, and so as to avoid conflicts and deep nesting, try to pull in just the identifiers you need with a using declaration instead. If for instance you only ever wanted to use class foo from first then there would be no ambiguity with the following:
using first::foo;
using namespace second;
using namespace ... directives do not create an ordered path; nor do they override all previous ones. So, yes, your code creates an ambiguous situation.
First you use namespace first, thus the myCout of the first namespace is introduced. Then you use namespace second, causing the other myCout to be come into play too. The second namespace does not override the previous namespace.
As a result, when you call myCout for the second time, there are two definitions into play, causing the compiler to rule this as an ambiguous call.
In other words:
int main(void)
{
using namespace first; // `myCout` of the 1st namespace is introduced
myCout();
using namespace second; // `myCout` of the 2nd namespace is introduced
// and does not override the first namespace!
myCout(); // Which `myCout`? Of the first or second?
return 0;
}

Difference in using namespace (std:: vs ::std::) [duplicate]

This question already has answers here:
why prepend namespace with ::, for example ::std::vector
(5 answers)
Closed 7 years ago.
using ::std::...;
VS
using std::...;
Is there a difference(s)? If so, which one(s)?
I saw this:
using ::std::nullptr_t;
which made me wonder.
In your case, there is most likely no difference. However, generally, the difference is as follows:
using A::foo; resolves A from the current scope, while using ::A::foo searches for A from the root namespace. For example:
namespace A
{
namespace B
{
class C;
}
}
namespace B
{
class C;
}
namespace A
{
using B::C; // resolves to A::B::C
using ::B::C; // resolves to B::C
// (note that one of those using declarations has to be
// commented for making this valid code!)
}
If you are inside another namespace that has its own nested std namespace, then ::std and std are different. A simple example:
#include <iostream>
namespace A {
namespace std {
void foo() { ::std::cout << "foo" << ::std::endl;}
}
//using std::cout; // compile error
using ::std::cout; //ok
using std::foo; // ok
//using ::std::foo; // compile error
}
Though definitely not a good practice to ever have a nested std namespace.
From: http://en.cppreference.com/w/cpp/language/using_declaration
Using-declaration introduces a member of another namespace into
current namespace or block scope
Therefore, if your current scope already has a class with the same name, there will be an ambiguity between the one you introduced and the one in your current namespace/block.
A using declaration is just a subset of a using directive. The using directives is defined as follows (http://en.cppreference.com/w/cpp/language/namespace):
From the point of view of unqualified name lookup of any name after a
using-directive and until the end of the scope in which it appears,
every name from namespace-name is visible as if it were declared in
the nearest enclosing namespace which contains both the
using-directive and namespace-name.
Thus, you can consider these two examples that display the issues that can arise.
It prevents ambiguity between namespaces that share the same name (example 1) as well as ambiguity between class names in different namespaces (example 2).
namespace A
{
namespace B
{
struct my_struct {};
}
}
namespace B
{
struct my_struct {};
}
using namespace A; // removing this line makes B:: resolve to the global B::
int main()
{
::B::my_struct; // from global, will not pick A::B::
B::my_struct; // error: 'B' is ambiguous, there is A::B:: and B::
}
Consider this example which showcases why people shun the use of using namespace std;
using namespace std;
template <typename T>
class vector
{ };
int main()
{
vector<int> v; // which one did you want? ambiguous
::vector<int> v_global; // global one
::std::vector<int> v_std; // std::vector<T>
}
It depends on where you use the using declaration. On a global namespace scope there will be no difference. However, if you have code like
#include <iostream>
#include <vector>
namespace my_namespace {
namespace std {
class vector {
};
}
using std::vector;
}
int main()
{
my_namespace::vector<int> v;
}
it will not compile unless you inform the compiler to search the global namespace -> std namespace -> vector in your declaration by stating using ::std::vector.

Using "using" directive to shorten function definition

I have stumbled upon an unusual to me usage of using namespace directive:
Given a header file WeirdNamespace.h:
namespace WeirdNamespace
{
class WeirdClass
{
public:
int x;
void go();
};
}
I have a matching 'WeirdNamespace.cpp`:
#include "WeirdNamespace.h"
#include <iostream>
using namespace WeirdNamespace;
void WeirdClass::go()
{
std::cout << "Reached go?!" << std::endl;
}
The class is used as follows:
#include "WeirdNamespace.h"
int main(int argc, const char * argv[])
{
WeirdNamespace::WeirdClass c;
c.go();
}
Until now I have never seen the using directive used to avoid reopening the namespace in the cpp file or prefixing method names with the namespace name. Is it a correct usage of the directive? Are there any pitfalls specific to this scenario, except for the usual using namespace caveats?
You might do:
namespace WN = WeirdNamespace;
WN::WeirdClass c;
Now, I got the question! The above is no answer.
Quoting from [7.3.4] Using directive
"During unqualified name lookup (3.4.1), the names appear as if they
were declared in the nearest enclosing namespace which contains both
the using-directive and the nominated namespace."
Hence your definition in the source without enclosing it in the namespace is fine.
Yes it is valid but there is a pitfall:
using namespace NamespaceName will make available all the names in NamespaceName.
So instead you can use using to use only the class name:
#include <iostream>
#include "WeirdNamespace.h"
using WeiredNamespace::WeiredClass;
void WeiredClass::go() {
// ...
}