结构/类声明中的Scoped using-directive? [英] Scoped using-directive within a struct/class declaration?

查看:365
本文介绍了结构/类声明中的Scoped using-directive?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现我的C ++ 头文件很难读取(真的很繁琐的类型)所有的全限定类型(深入到4嵌套的命名空间)。这是问题(所有的答案给出了凌乱的替代实现它,但这不是的问题): 有强烈的理由反对引入scoped使用指令在结构和类在C ++语言 (允许在函数中使用声明的范围)?



例如

  class Foo:public Bar 
{
using namespace System;
using namespace System :: Network;
使用命名空间System :: Network :: Win32 :: Sockets;
using Bar :: MemberFunc; //没有冲突这个

//例如我的头文件没有scoped使用指令
混乱我的头文件void FooBar(System :: Network :: Win32 :: Sockets :: Handle句柄,System :: Network :: Win32 :: Sockets :: Error&错误/ *,更完全限定的param声明... * /);
};

由于命名空间是关键字我们认为它足够明显,不会与范围使用声明冲突,例如 Bar :: MemberFunc



编辑:仔细阅读问题--->我加粗了。提醒:我们会在此处讨论如何提高示例的可读性。在C ++语言中建议如何实现范围使用指令(即通过添加关键字/构造等)是一个答案(如果你可以找到一个优雅的方式来实现这个使用现有的C + c>使用

c $ c>声明在类范围不继承,这可以工作。该名称只在该类声明内部或在嵌套类的声明内部有效。但我认为这是一个重载一个类的概念,一个想法应该更大。



在Java和Python中,个别文件以特殊的方式处理。您可以有 import 声明,将来自其他命名空间的名称注入到文件中。这些名称(以及不完全与Python,但太复杂,这里解释)只有在该文件中可见。



对我来说,这种能力不是绑定到类声明,而是给它自己的范围。这将允许注入的名称在几个类声明中使用,如果它是有意义的,或者甚至在函数定义。



这里是一个想法,我喜欢,因为它允许这些东西,仍然给你使用声明的类级别的好处:

 使用{
// A'using'一种方式来篱笆名称。唯一的名称
//逃避使用块的限制是不是
//别名的其他东西的名称,甚至不是不是有自己的名称
//。这些是类似于
//类,枚举,结构体,全局函数或全局变量的声明。
//新的非别名将被视为在
中声明的范围//using块出现的范围。

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 ;我_);
}

private:
const string st_;
mn :: mytype_t me_;
};
//所有typedef,使用声明和命名空间
//在这个块的级别引入的别名的效果消失
//这里。 typedef和使用嵌套类中的声明
//或命名空间声明不会消失。
} // end using。

//法律因为AClass被视为已在此
//范围中声明。
AClass a(Fred,:: mynamespace :: mytype_t(5));

//不合法,别名mn不再存在。
AClass b(Fred,mn :: mytype_t);

//不合法,不合格的名称myfunc不再存在。
AClass c(Fred,myfunc(:: mynamespace :: mytype_t(5));

这类似于在函数中声明一个局部变量的块,但在这种情况下,你声明一个非常有限的范围,你将改变名称查找规则。


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)!

解决方案

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.

这篇关于结构/类声明中的Scoped using-directive?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆