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() {
// ...
}
Related
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.
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.
For eg., when using OpenCV, we specify
using namespace cv;
But where does C++ look down to know where it is defined?
using namespace will not make everything declared in that namespace visible. It will expose only what translation unit "sees".
Consider following code
One.h
#pragma once
namespace ns
{
void function1();
}
Two.h
#pramga once
namespace ns
{
void function2();
}
main.cpp
#include "Two.h" // <-- included only Two.h
using namespace ns;
int main()
{
function2(); // <-- is a ns::function2() located in Two.h
function1(); // <-- error compiler does not know where to search for the function
return 0;
}
What happened here is the compiler created translation unit with all preprocessor directives resolved. It will look something like this:
namespace ns
{
void function2();
}
using namespace ns;
int main()
{
function2(); // <-- OK. Declaration is visible
function1(); // <-- Error. No declaration
return 0;
}
How does C++ know where to look for the namespace specified using using namespace …?
It doesn't.
When you use
using namespace cv;
the scope of search for names (of classes, functions, variables, enums, etc) is expanded. The names are searched in the cv namespace in addition to other scopes in which they are normally searched.
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.
Sorry for this silly question, but is there any way to restrict using directives to the current file so that they don't propagate to the files that #include this file?
No, there isn't, which is why you should not use using directives in header files, or any other file that you #include.
Perhaps wrapping the code to be included inside its own namespace could achieve the behavior
you want, since name spaces have scope affect.
// FILENAME is the file to be included
namespace FILENAME_NS {
using namespace std;
namespace INNER_NS {
[wrapped code]
}
}
using namespace FILENAME_NS::INNER_NS;
and in some other file
#include <FILENAME>
// std namespace is not visible, only INNER_NS definitions and declarations
...
Technically you should be able to import them to some internal namespace, and then make the things declared in that visible in the namespace meant for the user.
#ifndef HEADER_HPP
#define HEADER_HPP
#include <string>
namespace my_detail
{
using std::string;
inline string concatenate(const string& a, const string& b) { return a + b; }
}
namespace my_namespace
{
using my_detail::concatenate;
}
#endif
#include <iostream>
#include "header.hpp"
using namespace my_namespace;
int main()
{
std:: //required
string a("Hello "), b("world!");
std::cout << concatenate(a, b) << '\n';
}
Not sure if it is worth the trouble and how well it plays with "argument-dependent lookup".