在struct/class声明中使用using指令?

Zac*_*Saw 24 c++ language-features using-directives

我发现我的C++ 头文件很难用所有完全限定类型(比4个嵌套命名空间一样深)读取(并且输入真的很繁琐).这是一个问题(所有答案都提供了实现它的混乱替代方案,但这不是问题):是否有强烈的理由反对在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... */);
};
Run Code Online (Sandbox Code Playgroud)

既然namespace是一个关键字,我会认为它足够明显,不会与使用声明的范围发生冲突,例如Bar::MemberFunc.

编辑:仔细阅读问题--->我加粗了.提醒:我们不是在讨论如何提高示例的可读性.提示using指令范围的中如何实现在C++语言(通过增加关键字/结构等手段IE)是不是一个答案(如果你能找到实现这个使用现有的C++语言标准的一个优雅的方式,那么它会的当然是一个答案)!

Tim*_*imo 11

有时我这样做可以达到几乎相同的效果:

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;
Run Code Online (Sandbox Code Playgroud)

  • 我看到了.但这个问题有点无意义,因为它很可能没有答案.C++标准中的很多东西都没有意义. (5认同)
  • 当Foo需要完全限定解决歧义(`:: Foo`)时,这有Foo用户需要知道它在`detail`命名空间中的副作用.所以不,这里展示的是*不*实现同样的目标. (3认同)
  • 有时回答"为什么不允许X?" 是C++提供了另一种实现相同目标的方法 - 如此处所示. (2认同)

Omn*_*ous 9

鉴于using类范围的声明不是继承的,这可能有效.该名称仅在该类声明中有效,或在嵌套类的声明内有效.但我认为这有点超载一个类的概念,其概念应该更大.

在Java和Python中,单个文件以特殊方式处理.您可以拥有import将其他名称空间中的名称注入文件的声明.这些名称(嗯,不完全是Python,但在这里解释得太复杂)只能在该文件中可见.

对我来说,这种能力不是与阶级宣言联系在一起,而是考虑到自己的范围.如果有意义,甚至在函数定义中,这将允许注入的名称在几个类声明中使用.

这是一个我更喜欢的想法,因为它允许这些东西,同时仍然使用声明为您提供类级别的好处:

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));
Run Code Online (Sandbox Code Playgroud)

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

  • 通常,标准委员会的工作方式相反.是否有充分理由将*包含在语言中?C++已经是一门庞大的语言.每个新功能*真的*必须证明成本是合理的,以便添加.那么这个功能是否至关重要,足以证明语言更大? (3认同)
  • 我在理解整个`using {}`时遇到了一些麻烦.这是一个功能概念,而不是当前有效的C++构造,对吧?@ZachSaw,你为什么接受这个答案,如果它不是你想要的? (2认同)