Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么我能';t单独编写名称空间';头文件中的层次结构是什么?_C++_Visual Studio - Fatal编程技术网

C++ 为什么我能';t单独编写名称空间';头文件中的层次结构是什么?

C++ 为什么我能';t单独编写名称空间';头文件中的层次结构是什么?,c++,visual-studio,C++,Visual Studio,我写一些头文件。我想分别声明名称空间层次结构(为了清楚起见),然后声明函数和类。对我来说,它看起来就像文档中的目录。这对我来说非常方便:在一个地方查看名称空间的完整层次结构。我这样写: // Namespaces hierarchy: namespace Bushman{ namespace CAD_Calligraphy{} //... } // Declarations of classes and functions class Bushman::CAD_Calligra

我写一些头文件。我想分别声明名称空间层次结构(为了清楚起见),然后声明函数和类。对我来说,它看起来就像文档中的目录。这对我来说非常方便:在一个地方查看名称空间的完整层次结构。我这样写:

// Namespaces hierarchy:
namespace Bushman{
    namespace CAD_Calligraphy{}
    //...
}

// Declarations of classes and functions
class Bushman::CAD_Calligraphy::Shp_ostream{
public:
    explicit Shp_ostream(std::ostream& ost);
};
但是微软VisualStudio对这种头文件的创建方式大声疾呼。我应该这样写:

namespace Bushman{
    namespace CAD_Calligraphy{
        class Shp_istream{
        public:
            explicit Shp_istream(std::istream& ist);
        };
    }
}
为什么第一种变体不起作用?这是C++的限制,还是IDE?< /P> 另外,我的补充问题是


首先,C++不是被设计成这样工作的。因此,发生这种情况并不奇怪

但是,由于您使用的是Visual Studio,因此可以利用。不幸的是,这一特性似乎只与C++/CX有关,所以您可能无法使用它

您仍然需要在名称空间层次结构中声明一个分部类,但我猜它可能是空的

老实说,我没有使用过这个功能,我不知道它可以弯曲到什么程度才能达到你想要的。但无论如何,你可以试试看

请记住,这是一个VisualStudio扩展,因此您的代码不会跨平台


希望这有帮助。无论如何。

限制在§9/1中:“如果一个类头名称包含 嵌套名称说明符,类说明符应参考 以前直接在类或中声明的类 嵌套名称说明符引用的命名空间[…]。在里面 换句话说,类名的第一次出现不能在 类似于布什曼:CAD\U书法::Shp\U奥斯特拉姆

您可以做的是在初始值中添加前向声明 层次结构声明:

// Namespaces hierarchy:
namespace Bushman{
    namespace CAD_Calligraphy{
        class Shp_ostream;
        //...
    }
    //...
}

// Declarations of classes and functions
class Bushman::CAD_Calligraphy::Shp_ostream{
public:
    explicit Shp_ostream(std::ostream& ost);
};
根据标题的组织方式,这甚至可能是 从人的角度看更好:你的标题以
其中定义的一种索引。

引用标准:第7.3.1.2节第2点:

命名命名空间的成员也可以在该命名空间之外定义 名称空间(3.4.3.2)的显式限定 已定义,前提是已声明要定义的实体 在命名空间中,定义显示在 包含声明命名空间的命名空间中的声明

namespace Q {
  namespace V
    void f();
  }
  void V::f() { /∗ ... ∗/ }    // ok. 
  void V::g() { /∗ ... ∗/ }    // Error: g() is not yet a member of V
  namespace V
    void g();
  }
}

namespace R {
   void Q::V::g() { /∗ ... ∗/ }   // // error: R doesn’t enclose Q
}
因此,如果您在原始帖子中声明类名,您可以执行您在原始帖子中所做的操作:

namespace Bushman{
    namespace CAD_Calligraphy {
        class Shp_ostream;
        ...
    }
}
<>这就是C++的工作原理。< /P> 它与其他嵌套声明一致:不能从类外部向类添加成员:

class A
{
};

void A::f() { }  // Error!
并且不能从外部将枚举数添加到枚举:

enum E { E1 = 1, E2 = 2 };

E::E3 = 3;  // Error!
您需要“打开”范围并在范围内声明实体。声明后,您可以使用嵌套名称在该范围外定义它:

class A
{
  void f();  // declare
};

void A::f() { }  // define

它是C++的限制——我从未见过真正的代码中的“第一变型”,它不是“设计这样工作”的问题,而是标准中的任意限制。(对于“武断”的某些含义。可能是当它被引入时,有人有理由这样做。)抱歉,更改了链接。谢谢你的提醒,@DyP。无论如何,创建分部类的可能性似乎与C++/CX密切相关,因此OP可能不可能使用它。@James Kanze,不理解你的评论。C++中的命名空间机制被设计为以某种特定的方式(甚至引用您的答案中的标准文本),显然它不接受OP想要拥有的行为。另一个问题是是否可以这样做。@Baltasarq不允许OP想做的事情是一种限制。在我看来,这似乎是武断的,但我认为至少有一名委员会成员认为这是有充分理由的(并说服了其他人)。