结构/类声明中的作用域 using 指令?
我发现我的 C++ 头文件对于所有完全限定的类型(深达 4 个嵌套命名空间)都非常难以阅读(并且键入起来非常乏味)。这就是问题(所有答案都给出了实现它的混乱替代方案,但这不是问题):是否有强有力的理由反对在结构和类中引入作用域 using-directive在 C++ 语言中(虽然允许在函数中使用作用域声明)?
例如,
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... */);
};
由于 namespace
是一个关键字,我认为它足够独特,不会与作用域 using 声明(例如 Bar::MemberFunc
)发生冲突。
编辑:仔细阅读问题--->我已经加粗了。提醒:我们不讨论如何提高此处示例的可读性。建议如何在 C++ 语言中实现范围内的 using-directive(即通过添加关键字/构造等)并不是一个答案(如果您可以找到一种优雅的方法来使用现有的 C++ 来实现此目的)语言标准,那么这当然是一个答案)!
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)!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
有时我这样做是为了达到几乎相同的效果:
Sometimes I do this to achieve almost the same effect:
鉴于类作用域中的
using
声明不是继承的,因此这是可行的。该名称仅在该类声明内或嵌套类的声明内有效。但我认为这有点超载了类的概念,而它的想法应该更大。在 Java 和 Python 中,单个文件以特殊方式处理。您可以使用
import
声明将其他名称空间中的名称注入到文件中。这些名称(嗯,不完全是 Python,但这里解释起来太复杂)仅在该文件中可见。对我来说,这种能力不依赖于类声明,而是赋予它自己的范围。如果有意义的话,这将允许注入的名称在多个类声明中使用,甚至在函数定义中使用。
这是我更喜欢的一个想法,因为它允许这些事情,同时仍然为您提供使用声明的类级别的好处:
这类似于在函数中声明局部变量的块。但在这种情况下,您声明的范围非常有限,您将在其中更改名称查找规则。
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:
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.
您可以在类声明中使用 typedef 来实现相同的效果
You can use a typedef inside the class declaration to achieve the same
也许命名空间别名?
Maybe namespace alias?
命名空间的明显好处是它们可以让您避免命名冲突。然而,通过将整个命名空间引入到类声明中,这种好处就消失了。 System 命名空间中的函数完全有可能与您自己的 Bar::MemberFunc 函数发生冲突。当您添加注释“与此不冲突”时,您甚至会在示例代码中注意到这一点。
您显然不想像这样将整个名称空间引入到您的类中:
并且您不能将像这样的范围更窄的 using 语句添加到类声明中。将它们直接放入类声明中是非法的。
您可以做的是使用未命名的命名空间。因此,您的头文件将如下所示:
这具有三个明显的优点。
如果我错了,请纠正我;我只是简单地测试了这一点。很快就写了一个例子,并编译了。
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:
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.
What you can do is use the unnamed namespace. So, your header file would look something like this:
This has three distinct advantages.
Please correct me if I'm wrong; I only briefly tested this. Quickly wrote up an example, and it compiled.