This question already has answers here:
Why is "using namespace X;" not allowed at class/struct level?
(6 answers)
Closed 5 years ago.
I find that my C++ header files are quite hard to read (and really tedious to type) with all the fully-qualified types (which goes as deep as 4 nested namespaces). This is the question (all the answers give messy alternatives to implementing it, but that's not the question): Is there a strong reason against introducing scoped using-directive in structs and classes in the C++ language (while it's permissible to have scoped using-declaration in functions)?
e.g.
class Foo : public Bar
{
using namespace System;
using namespace System::Network;
using namespace System::Network::Win32::Sockets;
using Bar::MemberFunc; // no conflict with this
// e.g. of how messy my header files are without scoped using-directive
void FooBar(System::Network::Win32::Sockets::Handle handle, System::Network::Win32::Sockets::Error& error /*, more fully-qualified param declarations... */);
};
Since namespace is a keyword, I would've thought it's distinct enough to cause no conflict with the scoped using declaration such as Bar::MemberFunc.
EDIT: Read the question carefully ---> I've bolded it. Reminder: we're not discussing how to improve readability of the example here. Suggesting how scoped using-directive could be implemented (i.e. by means of adding keywords / constructs etc.) in the C++ language is NOT an answer (if you could find an elegant way to implement this using existing C++ language standards, then it would of course be an answer)!
Sometimes I do this to achieve almost the same effect:
namespace detail {
using namespace System;
using namespace System::Network;
using namespace System::Network::Win32::Sockets;
class Foo : public Bar
{
void FooBar(Handle handle, Error& error);
};
}
using detail::Foo;
Given that using declarations at class scope are not inherited, this could work. The name would only be valid inside that class declaration, or inside the declarations of nested classes. But I think it's sort of overloading the concept of a class with an idea that should be larger.
In Java and Python individual files are treated in a special way. You can have import declarations that inject names from other namespaces into the file. These names will (well, not exactly with Python, but it's too complicated to explain here) only be visible within that file.
To me that argues for this sort of ability not being tied to a class declaration, but given a scope of its own instead. This would allow injected names to be used in several class declarations if it made sense, or even in function definitions.
Here is an idea I prefer because it allows these things while still giving you the benefits of a class level using declaration:
using {
// A 'using' block is a sort of way to fence names in. The only names
// that escape the confines of a using block are names that are not
// aliases for other things, not even for things that don't have names
// of their own. These are things like the declarations for new
// classes, enums, structs, global functions or global variables.
// New, non-alias names will be treated as if they were declared in
// the scope in which the 'using' block appeared.
using namespace ::std;
using ::mynamespace::mytype_t;
namespace mn = ::mynamespace;
using ::mynamespace::myfunc;
class AClass {
public:
AClass(const string &st, mytype_t me) : st_(st), me_(me) {
myfunc(&me_);
}
private:
const string st_;
mn::mytype_t me_;
};
// The effects of all typedefs, using declarations, and namespace
// aliases that were introduced at the level of this block go away
// here. typedefs and using declarations inside of nested classes
// or namespace declarations do not go away.
} // end using.
// Legal because AClass is treated as having been declared in this
// scope.
AClass a("Fred", ::mynamespace::mytype_t(5));
// Not legal, alias mn no longer exists.
AClass b("Fred", mn::mytype_t);
// Not legal, the unqualified name myfunc no longer exists.
AClass c("Fred", myfunc(::mynamespace::mytype_t(5));
This is analogous to declaring a block for local variables in a function. But in this case you are declaring a very limited scope in which you will be changing the name lookup rules.
Maybe namespace alias?
namespace MyScope = System::Network::Win32::Sockets;
You can use a typedef inside the class declaration to achieve the same
class Foo : public Bar
{
typedef System::Network::Win32::Sockets::Handle Handle;
typedef System::Network::Win32::Sockets::Error Error;
void FooBar(Handle handle, Error& error);
};
The obvious benefit of namespaces is that they allow you to avoid naming conflicts. However, by introducing an entire namespace into a class declaration, this benefit is voided. It's entirely possible that a function in the System namespace could conflict with your own Bar::MemberFunc function. You even note this in your sample code when you added the comment "no conflict with this".
You obviously don't want to introduce entire namespaces into your class like this:
using namespace System;
using namespace System::Network;
using namespace System::Network::Win32::Sockets;
And you can't add more narrowly scoped using statements like this into a class declaration. Putting these directly into a class declaration is illegal.
using System::Network::Win32::Sockets::Handle;
using System::Network::Win32::Sockets::Error;
What you can do is use the unnamed namespace. So, your header file would look something like this:
namespace {
using System::Network::Win32::Sockets::Handle;
using System::Network::Win32::Sockets::Error;
}
class Foo : public Bar
{
using Bar::MemberFunc;
// clean!
void FooBar(Handle handle, Error& error /*, more declarations*/);
};
This has three distinct advantages.
The contents of entire namespaces are not introduced. This helps to more easily avoid naming conflicts.
You have a list, before your class declaration, of what your class depends upon to work correctly.
Your function declarations are clean.
Please correct me if I'm wrong; I only briefly tested this. Quickly wrote up an example, and it compiled.
Related
I remember being told that C++ classes have their own namespaces, and that the class name could be used as a namespace for scope resolution, like this:
// Example.h
class Example {
void Private();
public:
void Public();
}
and, later in a manner similar to this:
// Example.cpp
#include "Example.h"
using /*namespace*/ Example;
void Private() {}
void Public() {}
instead of:
// Example.cpp
#include "Example.h"
void Example::Private() {}
void Example::Public() {}
but I couldn't find neither an explanation nor an example of that in my books. A brief Google search was also a dead-end. Is this a real thing?
No, namespaces and classes are different.
However, namespaces and classes both introduce a scope which may be referred to using the scope resolution operator :: .
The using namespace N; declaration can only apply to namespaces. It's not possible to do something similar for a class. You can only do using Example::x; for specific names x inside Example to import them one by one.
When providing the member function body out-of-line, you must write Example::Private(), there is no alternative.
Yes, Every class has its own namespace that everything part of the class declaration belongs to.
You may employ the using directive as you indicate as explained here.
It should be noted that you cannot declare a namespace with the same name as a class as shown here:
namespace fubar
{
class snafu
{
...
};
}
// Cannot do stuff below (ERROR)
namespace fubar::snafu;
{
// this is not valid, once a class always a class
// once a namespace, always a namespace
// a class makes a namespace also but never JUST a namespace
}
Do be careful though. 'Using' too much can play real tricks on you and those who inherit your code.
this is a technical question as well as (if it's technically feasible) a style question. In my code I have a series of functions that load and manipulate a file. For different syntax these functions exist in separate namespaces, so that:
namespace typeA {
void load();
void manipulate();
};
namespace typeB {
void load();
void manipulate();
};
In this minimal example, obviously I could simple have a clause that checks for the file type and then calls typeA:load() and typeB:load() etc. as required.
However, I was wondering if it is also possible to do this using namespace aliases? It would make the code cleaner as there are several dozen calls to functions in the namespaces which all would need a separate if/else clause.
What I've tried:
namespace my_type = (ft == "type_A") ? typeA : typeB;
...
my_type::load();
which doesn't compile with an error in the namespace alias assignment line.
Is there another way of doing this / what is the generally accepted clean way of handling situations like this?
I suppose a virtual class and inheritance for each file type would be one option. Are there others?
There is no way to do such namespace alias.
3.4.6 Using-directives and namespace aliases [basic.lookup.udir]
1 In a using-directive or namespace-alias-definition, during the lookup for a namespace-name or for a name in
a nested-name-specifier only namespace names are considered.
You an use partial template specialization to solve that.
I've got an argument with my colleague.
We have a class that is a member of a namespace (which is a member of the other namespace but that is not important here I think). In the header file, we nest the class block into the namespace block like this:
namespace NS {
class A {
void method();
// ...
};
}
And here is the .cpp file and the subject of our argument. I wrote:
using namespace NS;
void A::method() {
// ...
}
The colleague told me that I use the 'using' directive improperly, and I should have used here the same NS { ... } as in the header. (He's modified the code and got some compiler errors that he only managed to get rid of by removing the using directive and surrounding the code with NS { ... }.)
My point is that 'using' just affects the name lookup so A is looked for in the NS namespace, so my approach is correct, and his compiler problems were caused by something else but not by that 'using' directive.
Who is right and why?
Added: guys, please don't answer like 'I did this (or that) way many times', that's not much useful. We need the theory here: why this or that approach is right or wrong.
Your colleague is correct, you should wrap cpp with namesapce which means you define your funcitons inside namesapce NS.
namespace NS
{
void A::method()
{
// ...
}
}
You may get conflict name lookup if you have multiple A available.
The dangerous thing happening here is that the using declaration takes a snapshot of whatever entities named A::method in namespace NS have been seen by the time the using declaration is encountered.
Have a read of Google cpp style guilde regarding namespace, also 101 c++ coding standards
Both of you are right in different ways. You are right in that the using directive will let the compiler resolve A in void A::method() to be NS::A, but he is also right in that in most cases you are better off opening the namespace.
The reason is that not everything that is declared in the namespace in the header will be looked up, and for those elements you will need to open the namespace (or provide the qualification manually), so it makes sense to provide a uniform approach.
A common example is the definition of operators that are applied to the type:
// header
namespace NS {
class A { ... };
std::ostream& operator<<(std::ostream&,A const&);
}
// implementation file (incorrect):
using namespace NS;
std::ostream& operator<<(std::ostream& o, A const & a) {
// do something
}
The problem here is that function definitions (when the function name is not a qualified name) are self-declaring. In the header the operator is declared as ::NS::operator<<, but in the implementation file it is defined as std::ostream& ::operator<<(std::ostream&, NS::A const&). The using directive will allow the resolution of the A identifier to be NS::A, but it won't make that function definition reside in the NS namespace.
This leads to a subtle problem, where any use of that operator will find ::NS::operator<< due to ADL, but that operator is not defined anywhere (although there is a similar operator in a different namespace)
Having said all that, there are some coding conventions (where I work now has such a guideline) that require namespaces for all types and that free function definitions should be performed outside of the namespace and always qualified to avoid self declarations. In the example above, the operator would be defined in the implementation file as:
std::ostream& ::NS::operator<<(std::ostream& o, A const& a) { ... }
But unless you really get used to always qualifying, this is prone to errors if you forget the qualification of the function.
namespace NS {
class A {
void method();
// ...
};
}
Always done it that way...
It turns out it's not only "coding-style matter". Using namespace ... leads to linking error when defining and initializing a variable declared extern in header file. Take a look at example in my question. Definition of constant within namespace in cpp file
You are correct. I've been bitten by this a number of times (that is, bitten by thinking that using declarations don't do this). There are three ways you could write this, and all will work:
namespace NS
{
void A::method()
{ }
}
Or:
NS::A::method() { }
Or:
using namespace NS;
A::method() { }
However, in terms of style, I would suggest either the first or the second - using declarations can get hairy when you have multiple classes with the same name and methods around.
It is considered good practice not to use 'using namespace' in code declarations or libraries but its OK to use them for the actual program's code.
Ie: dont use it for the Cpp definition but you can use it when your calling the function/class outside.
This is all just good coding practice and unless other people are using your code it matters more what you want.
The best is to put the cpp code into Namespace { ... } for readability
Like :
using ::size_t; using ::fpos_t; using ::FILE;
In fact it's a question inspired by the comment under this question:
When is .h not needed to include a header file?
This is called using declaration. There are actually two ways you can use the using keyword. There is a third special form of using declarations used inside class definitions, but i'll focus on the general using declaration here. (see below).
using declaration
using directive
These have two very different effects. A using declaration declares a name to be an alias to another declaration or a set of declarations (if you were to name a set of overloaded functions). The name is declared in the current scope. That is, you can use it inside blocks too
int main() {
using std::swap;
// ...
}
This is quite useful if you use a name very often locally and you don't want to prefix it in all uses, and it's also useful in implementing the swap using argment dependent lookup idiom.
A using directive names a namespace and does not declare any names. Instead it will modify name lookup to find names that aren't really declared where it thinks they are. For unqualified name lookup, it find names declared in the enclosing namespace that encloses both the using directive and the target namespace. All names that are declared in the target namespaces will be found:
int cout;
int main() {
using namespace std;
// cout << 1; ambiguous!
}
Here, cout will be thought as being declared twice in the global namespace, and causes an ambiguity (:: encloses both main and std). In qualified namelookup, it will build the transitive closure of a namespace with all the namespaces named in using directives.
using namespace foo;
int main() {
::c++;
}
c is not only looked up in the global namespace, but also in the namespace foo and in the namespaces that foo has using directives for and so on. If however the global namespace would contain a direct declaration (including a using declaration), that declaration will hide the declarations found indirectly by using directives:
using namespace foo;
int c;
int main() {
::c++; // not ambiguous!
}
Using declarations can appear in many places, including inside class definitions. Its meaning is similar to its meaning otherwhere with an important restriction: It declares a name to be an alias to one or more declarations, but the declarations must be members of a base class. This is very useful for making names visible in a derived class that would otherwise be hidden by the same name declared there
struct base {
void f();
};
struct derived : base {
using base::f; // name "f" declared in derived
void f(int); // overloads the using declaration
};
Now you can call d.f(). If there were no using declaration, then name lookup would only find one declaration of f in derived and stop lookup, not delving into the base class scope:
derived d;
d.f(); // invalid without the using declaration
d.f(0); // valid with or without the using declaration
// explicitly starting lookup in base: valid with or without the using declaration
d.base::f();
It also allows to change the accessibility of base-class members, although you should use that sparingly :)
In practice, i found it useful for making virtual member function re-visible:
struct base {
virtual void f();
virtual void f(int);
};
struct derived : base {
// using base::f; would solve it
virtual void f() { ... }
};
Oops - now d.f(0); is invalid because name lookup only finds the zero parameter f! The using directive would solve it. Notice that if you alias a function declaration that has the same parameter types and constness as an explicit declaration (like f() in this case), then the explicit declaration will still hide the one that the using declaration is an alias for - so both f() functions won't conflict in this case.
An alternative to solve this is using the non-virtual interface idiom
struct base {
void f() { do_f(); }
void f(int) { do_f(0); }
private:
virtual void do_f();
virtual void do_f(int);
};
struct derived : base {
private:
virtual void do_f() { ... }
};
struct derived1 : derived {
private:
virtual void do_f(int) { ... }
};
Now, both d.f(0) and d.f() are valid no matter on what object you call it.
Unfortunately the example you're looking at is obscure.
using ::_Filet;
As others have noted, the using declaration makes a name from the specified namespace available in the current namespace. In that file there appear to be no namespaces opened, so you'd assume the current namespace is the global namespace, and also the :: with nothing before it addresses the global namespace. So here we seem to be moving a name from the global namespace into the global namespace. What's up with that?
The answer is in the use of a macro:
_STD_BEGIN
This is defined as namespace std {. So what the using declarations are doing is making those names appear in the std namespace, where otherwise they would only be in the global namespace.
using <some symbol> pull a symbol from its namespace into the current namespace. Assume the following code:
namespace foo {
// Assume you want to use std::string, you can either do
std::string bar;
// or
using std::string;
string bar;
}
As you can see, you can either qualify the symbol using its namespace (first line of code) or the second way. For symbols you use quite often, pulling them into the namespace tends to make the code a little more readable but if you have a conflict (say, foo contains a string class of its own which is bad practise but might happen), qualifying it with the appropriate namespace will allow you to resolve the conflict.
The namespace :: is a special case as it refers to the global namespace; in this particular case, the functions you're referring to are C functions and C doesn't know about C++ namespaces, so they end up in the global namespace.
Namespaces in C++ are a very powerful mechanism to avoid symbol naming clashes and I'd strongly encourage any C++ programmer to use them.
The 'using' keyword allows you to bring names from a namespace into the current namespace.
If you would like to use a name inside a namespace without bringing them into your current namespace, you would have to use the <namespace name>::<name> format, as in the following:
std::cout << "Hello World";
If cout is brought into the current namespace, then you can use it like below:
cout << "Hello World";
The using keyword can be used the following ways:
As a using directive (using namespace <namespace name>;):
using namespace std;
This brings all names inside the std namespace into the current namespace.
As a using declaration (using <namespace>::<member name>;):
using std::cout;
This brings only the std::cout name into the current namespace.
using makes a name from the specified namespace available in the current namespace.
Is it legal?
class SomeClass {
public:
static void f();
};
using SomeClass::f;
Edit: I forgot to qualify function. Sorry.
No, it is not. The using keyword is used to bring one or all members from a namespace into the global namespace, so that they can be accessed without specifying the name of the namespace everytime we use the members.
In the using statement you have given, the name of the namespace is not provided. Even if you had provided SomeClass there with a statement like using SomeClass::f; also, it won't work because SomeClass is not a namespace.
Hope this helps.
I think that using x; is normally used inside a class to bring method names from a base class into scope to avoid hiding base class methods.
You might be thinking of using namespace name; which only applies to namespaces.
You may be better off with a simple in-line function:
void f(){ SomeClass::f(); }