Areas using directives in a struct / class declaration?

I find that my C ++ header files are pretty hard to read (and very tedious to type) with all fully qualified types (which take up to 4 nested namespaces). This is a question (all answers give random alternatives to its implementation, but this is not a question): Is there a good reason not to introduce a cloud directive directive in C ++ structures and classes (while it is allowed to use declaration functions in functions)?

eg.

class Foo : public Bar { using namespace System; using namespace System::Network; using namespace System::Network::Win32::Sockets; using Bar::MemberFunc; // no conflict with this // eg 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 think that it is distinct enough not to cause a conflict with the scope using the declaration, for example Bar::MemberFunc .

EDIT: read the question carefully ---> I highlighted it. Reminder: we are not discussing how to improve the readability of the example here. The idea of ​​how to implement the implemented directive using (for example, by adding keywords / constructs, etc.) in C ++ is NOT the answer (if you could find an elegant way to implement this using existing language standards C ++, then this is of course the answer)!

+23
c ++ language-features using-directives
Dec 06 2018-10-12T00:
source share
5 answers

Given that using declarations in the class scope are not inherited, this might work. The name will only be valid inside this class declaration or within declarations of nested classes. But I think this overloads the concept of a class with an idea that should be bigger.

In Java and Python, individual files are processed in a special way. You may have import declarations that enter names from other namespaces in the file. These names will (well, not quite with Python, but it's too hard to explain here) will only be visible inside this file.

It seems to me that this ability is not tied to a class declaration, but instead has its own scope. This would allow you to enter the entered names in several class declarations, if that made sense, or even in function definitions.

Here is the idea I prefer because it allows these things, while still giving you class-level advantages with the 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 similar to declaring a block for local variables in a function. But in this case, you declare a very limited scope in which you will change the rules for finding names.

+10
Dec 6 2018-10-12T00:
source share

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; 
+10
Dec 06 '10 at 5:17
source share

Could be a namespace alias?

 namespace MyScope = System::Network::Win32::Sockets; 
0
Dec 06 '10 at 3:12
source share

You can use 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); }; 
0
Mar 04 '14 at 9:09
source share

The obvious advantage of namespaces is that they avoid name conflicts. However, by introducing the full namespace into the class declaration, this advantage is invalidated. It is possible that a function in the System namespace may conflict with your own Bar :: MemberFunc function. You even noticed this in your code example when you added the comment "there is no conflict with this."

Obviously, you do not want to introduce integer namespaces into your class as follows:

 using namespace System; using namespace System::Network; using namespace System::Network::Win32::Sockets; 

And you cannot add narrower scopes with such statements to the class declaration. Entering them 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 an unnamed namespace. So your header file will 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 whole namespaces are not entered. This helps to avoid name conflicts more easily.
  • You have a list before declaring a class that your class depends on the proper operation.
  • Your feature ads are clean.

Please correct me if I am wrong; I just checked it out briefly. Quickly wrote an example and it compiled.

-2
Dec 06 '10 at 5:36
source share



All Articles