为什么我们不能在类中声明命名空间别名?

Ran*_*agg 14 c++ namespaces

看起来在类中声明命名空间别名是不可能的; 但是我们可以在功能级别这样做(用g ++ 4.3.4测试):

namespace A
{
}

class C
{
  namespace N = A; // error: expected unqualified-id before `namespace'
};

class D
{
  void f();
};

void D::f()
{
  namespace N = A; // OK
}
Run Code Online (Sandbox Code Playgroud)

知道为什么存在这样的限制吗?这似乎与可以在类中声明的typedef非常一致.

Umm*_*mma 6

根据C++标准3.3.6

以下规则描述了在类中声明的名称范围.

1)在类中声明的名称的潜在范围不仅包括名称声明符后面的声明性区域,还包括该类中所有函数体,默认参数和构造函数ctor-初始化器(包括嵌套类中的这些内容) ............

因此,您只能在类范围内声明此列表中的内容.在类范围内声明任何其他内容无效.不仅是命名空间联盟,还有命名空间.例如

class myClass
{
    //compilation error !!!
    namespace myNamespace
    {
    }
    using namespace std;//another compilation error
}
Run Code Online (Sandbox Code Playgroud)

编辑:

知道为什么存在这样的限制吗?这似乎与可以在类中声明的typedef非常一致.

因为在类中使用typedef是非常有用的(例如vector<int>::iterator),而对于名称空间,它是无用的.考虑以下代码

class myClass
{
   namespce N=std;
};

//now let's use N
MyClass::N::vector<int> v;//don't you think, that this syntax is horrible, and useless?????
Run Code Online (Sandbox Code Playgroud)

为了比较,看看它在功能上做了什么

void f()
{
    namespace bnu= boost::numeric::ublas;
    bnu::matrix<int> m;//and now we can use short name bnu
}
Run Code Online (Sandbox Code Playgroud)

对于类,我们可以在CPP文件中声明命名空间联盟,有 没有需要到daclare它在类的声明.


Ton*_*ony 5

我不是C++标准的专家,但我会坚持不懈地回答你的问题.我假设namespace N = A在类声明中的使用违反了如何定义类成员的定义.

C++标准将类成员定义为

member-specification:
  member-declaration member-specification_opt
  access-specifier : member-specification_opt
member-declaration:
  decl-specifier-seq_opt member-declarator-list_opt ;
  function-definition ;opt
  ::opt nested-name-specifier templateopt unqualified-id ;
  using-declaration
  static_assert-declaration
  template-declaration
member-declarator-list:
  member-declarator
  member-declarator-list , member-declarator
member-declarator:
  declarator pure-specifier_opt
  declarator constant-initializer_opt
  identifier_opt : constant-expression
pure-specifier:
  = 0
constant-initializer:
  = constant-expression
Run Code Online (Sandbox Code Playgroud)

重要的一点是=在声明中,编译器期望使用pure-specifier或constant-initializer语句,并且由于该行不以零结尾,因此在这种情况下我们不应用纯指定符.

分析namespace N = A编译器将其视为的声明

declarator = constant-expression
Run Code Online (Sandbox Code Playgroud)

由于namespace是关键字,因此无法使用.

typedef 是允许的(因为标准)

嵌套类型是类中定义的类和枚举,以及使用typedef声明声明为成员的任意类型.