为什么我们不能声明一个类中的一个命名空间?(Why can't we declare a n

2019-07-04 00:32发布

在类中声明一个类是有效的。 (嵌套类)

声明一个类中的一个命名空间是无效的。

现在的问题是:有没有什么好的理由(比C ++语法/句法问题等)禁止类内的命名空间的声明?


至于为什么我会想要做的是,这里是个例:

让我们二叉树容器的基本delcaration

template<typename Data>
class binary_tree
{
 public:
  ... stuff ....     

 private:
  ... iterators class declaration ...

 public:
  typedef left_depth_iterator_impl     left_depth_iterator;
  typedef right_depth_iterator_impl    right_depth_iterator;
  typedef left_breadth_iterator_impl   left_breadth_iterator;
  typedef right_breadth_iterator_impl  right_breadth_iterator;

  ... stuff ....     

 private:
  Data         data;
  binary_tree* left;
  binary_tree* right;
};

现在我发现有很多在我的课迭代器,所以我想在同一个命名空间这样的内重组它们:

template<typename Data>
class binary_tree
{
 public:
  ... stuff ....     

 private:
  ... iterators class declaration ...

 public:
  namespace iterator
  {
    typedef left_depth_iterator_impl     left_depth;
    typedef right_depth_iterator_impl    right_depth;
    typedef left_breadth_iterator_impl   left_breadth;
    typedef right_breadth_iterator_impl  right_breadth;
  }

  ... stuff ....     

 private:
  Data         data;
  binary_tree* left;
  binary_tree* right;
};

这将允许简单的用法:

void  function()
{
  binary_tree::iterator::left_depth   it;

  ...stuff...
}

这工作如果我使用一个类,而不是一个命名空间的,但后来我不得不宣布,将永远不会被实例化这是一个相当命名空间中的类。

为什么允许嵌套类和类内禁止嵌套的命名空间? 它是一个传统的负担?


与不只有标准(尤其是语法部分)的报价部分语义原因答案将apreciated :)

Answer 1:

有没有真正的优势,加入这样的功能的语言。 特点一般不被添加,除非有需求。

什么会在类的命名空间给你买? 你真的不如说binary_tree::iterator::left_depth而不是简单地binary_tree::left_depth ? 或许,如果你里面有多个名称空间,您可以使用它们来区分说binary_tree::depth_iterator::leftbinary_tree::breadth_iterator::right

在任何情况下,你可以使用内部类作为一个贫穷的程序员的名字空间,这更加之所以有没有为内部类真正的命名空间需求达到预期的效果。



Answer 2:

既然你问的标准任务命名空间位置的这部分,我们打的了第一:

C ++ 11 7.3-P4:每个命名空间的定义应出现在全局范围内或在命名空间范围(3.3.6)。

关于类定义内声明命名空间的命题,我带你到...

C ++ 11 9.2-P2:A类被认为是在类说明符的关闭}完全定义的对象类型(3.9)(或完全型)。 内的类成员-说明书中,类被认为是功能体,默认参数,异常规格范围内完成,及大括号或相等-初始化用于非静态数据成员(包括嵌套类这样的事情)。 否则,在其自己的类成员的规范中被视为不完整的。

人机工程学,一旦达到后花类定义是有限的。 它不能备份打开和扩展(推导是不同的东西,但它不是延长刚刚定义的类 )。

但潜伏在一个命名空间的标准定义的最开始是扩大它的能力; 扩大它缺乏一个更好的词:

C ++ 7.3-P1:命名空间是任选命名声明性区域。 一个命名空间的名称,可以使用该命名空间中声明的访问实体; 也就是说,命名空间的成员。 不同于其他声明的区域,命名空间的定义可以在一个或多个翻译单元几个部分进行分割。 (强调)。

因此,一个类中的一个命名空间会违反在7.3-P4的定义。 假设不存在,将有可能在任何地方声明命名空间,包括一类,但因为一个类的定义形式化一旦关闭,你会只剩下做,如果你保持以下的能力符合7.3-P1:

class Foo
{
   namespace bar
   {
       ..stuff..
   }

   .. more stuff ..

   namespace bar
   {
       ..still more stuff..
   }
};

这个功能的实用性很可能争论了约3全秒前成立7.3-P4予以解决。



Answer 3:

我要在这里与他人不同意。 我不会说有没有真正的优势。 有时候,我只是想,无需额外的影响来隔离代码。 作为一个例子,我一个多线程ringbuffer模块中是工作,希望分割状态部件,其中一些是原子和/或存储器排列的,进命名空间为生产者和消费者。

通过刚刚命名的一切与producerconsumer前缀(这是我目前烦人的实现),我添加的污染,使代码难以阅读。 例如,当一切都被生产者拥有与开始producer ,它读它时,意外地自动更正是为你的大脑更容易producerProducerTimer (生产者计时器的生产复印件)作为producerConsumerTimer (消费者定时器的生产者阴影)或consumerProducerTimer (生产者定时器的消费阴影)。 调试方式需要时间比它需要,因为代码不再skimmable。

通过创建一个嵌套类/结构:

  • 我可以给下一个开发谁维护该代码的想法,其中多于一个可以/应该被实例化,复制,并分配给彼此一个范围内,所以现在,而不是只担心命名我也有= delete这些东西。
  • 我可以添加内存占用与结构对齐填充的背景下,可能没有其他必要的。
  • 使所有成员静态是不是一种选择,因为不止一个上下文可以被实例化,这将需要自己的生产者/消费者状态变量。
  • 这样的结构的功能不再有权访问其它构件数据或功能,诸如常数或由双方共享的功能,而是必须把这些东西作为参数。

理想情况下,我希望能够改变这样的事情:

rbptr producerPosition;
rbptr consumerPosition;

为此:

namespace producer
{
    rbptr position;
}
namespace consumer
{
    rbptr position;
}

然后,只应触及消费者的成员函数可以使用消费者的命名空间,需要触及这两个功能只应触及生产者成员可以使用生产者名称空间,功能有明确限定它们。 有会是没有办法碰触消费者变量在唯一使用生产者命名空间的功能。

在这种情况下,渴望纯粹是为了降低生产和消费的东西拷贝之间命名冲突,并减少命名冲突是存在哪些命名空间。 出于这个原因,我支持能够声明在类的命名空间的建议。



Answer 4:

这仅仅是不是命名空间的点。 命名空间应当存在接近的代码顶层,这样如果两个不同的公司(或代码库)可相互混合代码。 在更微观的层面,我既IMAP电子邮件访问和SMTP的电子邮件发送代码和(可能,我大大简化)在任一模块称为类Email是有很大的不同,但我有一个应用程序,比如邮件客户端来说,要同时使用同一类,例如,也许它转发邮件从一个帐户到另一个。 命名空间/包名/等允许这样做。

你提出根本就不是什么命名空间 - 在一个文件中,你能够给的东西不同的名称,因为笔者有文件的全局知识,虽然这是不正确的,当两家公司要共享的代码或两个应用程序那不知道他们会在任何时候发生碰撞。



Answer 5:

只是我觉得一个小的想法是值得一提。 一个使用类命名空间内将是一个功能相当于模板的命名空间。

template<class...types>
struct Namespace {
    namespace Implementation {
        ...
    }
};

// somewhere else

using namespace Namespace<types...>::Implementation;

// use templated stuff.

就个人而言,我很喜欢这个功能,但似乎需求不够高为它来实现。



文章来源: Why can't we declare a namespace within a class?