4

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

// 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);
};

但是 MS Visual Studio 对这种头文件的创建方式大喊大叫。我应该这样写:

namespace Bushman{
    namespace CAD_Calligraphy{
        class Shp_istream{
        public:
            explicit Shp_istream(std::istream& ist);
        };
    }
}

为什么第一个变体不起作用?这是 C++ 还是 IDE 的限制?

PS我的附加问题是here

谢谢你。

4

4 回答 4

10

限制在第 9/1 节中:“如果类头名称包含嵌套名称说明符,则类说明符应引用先前直接在嵌套名称所在的类或命名空间中声明的类-说明符指的是[...]”。换句话说,类名的第一次出现不能是Bushman::CAD_Calligraphy::Shp_ostream.

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

// 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);
};

根据您的标头的组织方式,从人类的角度来看,这可能会更好:您的标头以其中定义的某种索引开始。

于 2013-07-12T09:07:06.080 回答
2

引用标准:第 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;
        ...
    }
}
于 2013-07-12T09:14:02.077 回答
1

这就是 C++ 的工作原理。

它与其他嵌套声明一致:您不能从类外部向类添加成员:

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
于 2013-07-12T09:18:28.843 回答
-1

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

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

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

说实话,我没用过这个功能,也不知道能弯曲多远,才能达到你想要的效果。但无论如何你都可以试一试。

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

希望这可以帮助。不知何故。

于 2013-07-12T09:04:50.183 回答