在 C++ 中,啥是“命名空间别名”?

Posted

技术标签:

【中文标题】在 C++ 中,啥是“命名空间别名”?【英文标题】:In C++, what is a "namespace alias"?在 C++ 中,什么是“命名空间别名”? 【发布时间】:2010-11-15 17:35:43 【问题描述】:

什么是 C++ 中的“命名空间别名”?它是如何使用的?

【问题讨论】:

【参考方案1】:

命名空间用于防止名称冲突。

例如:

namespace foo 
    class bar 
        //define it
    ;


namespace baz 
    class bar 
        // define it
    ;

您现在有两个类名称栏,由于命名空间,它们完全不同且分开。

您展示的“使用命名空间”是为了让您不必指定命名空间即可使用该命名空间中的类。即 std::string 变为字符串。

我的资源:@​​987654321@

【讨论】:

【参考方案2】:

还要注意命名空间别名和 using 指令是在编译时解析的,而不是在运行时解析的。 (更具体地说,它们都是用于告诉编译器在解析名称时在哪里寻找其他工具,如果它无法在当前范围或其任何父范围中找到特定符号。)例如,这些都不会编译:

namespace A 
    int foo;
    namespace AA 
        int bar;
     // namespace AA
    namespace AB 
        int bar;
     // namespace AB
 // namespace A
namespace B 
    int foo;
    namespace BA 
        int bar;
     // namespace BA
    namespace BB 
        int bar;
     // namespace BB
 // namespace B

bool nsChooser1, nsChooser2;
// ...

// This doesn't work.
namespace C = (nsChooser1 ? A : B);
C::foo = 3;

// Neither does this.
// (Nor would it be advisable even if it does work, as compound if-else blocks without braces are easy to inadvertently break.)
if (nsChooser1)
    if (nsChooser2)
        using namespace A::AA;
    else
        using namespace A::AB;
else
    if (nsChooser2)
        using namespace B::BA;
    else
        using namespace B::BB;

现在,好奇的人可能已经注意到constexpr 变量也在编译时使用,并且想知道它们是否可以与别名或指令一起使用。据我所知,他们不能,尽管我可能错了。如果您需要在不同命名空间中使用同名变量,并在它们之间动态选择,则必须使用引用或指针。

// Using the above namespaces...
int& foo = (nsChooser1 ? A::foo : B::foo);

int* bar;
if (nsChooser1) 
    if (nsChooser2) 
        bar = &A::AA::bar;
     else 
        bar = &A::AB::bar;
    
 else 
    if (nsChooser2) 
        bar = &B::BA::bar;
     else 
        bar = &B::BB::bar;
    

上面的用处可能有限,但应该能达到目的。

(对于我在上面可能遗漏的任何错别字,我深表歉意。)

【讨论】:

【参考方案3】:

更多关于这个话题http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n

这就是为 looong 命名空间名称选择别名,例如:

namespace SHORT = NamespaceFirst::NameSpaceNested::Meow

然后,你可以键入def

typedef SHORT::mytype

而不是

typedef NamespaceFirst::NameSpaceNested::Meow::mytype

此语法仅适用于命名空间,不能包含类、namespace NAME = 之后的类型

【讨论】:

【参考方案4】:

很简单,#define 不起作用。

namespace Mine  class MyClass  public: int i; ; 
namespace His = Mine;
namespace Yours  class Mine: public His::MyClass  void f()  i = 1;  ; 

编译正常。让您可以解决命名空间/类名冲突。

namespace Nope  class Oops  public: int j; ; 
#define Hmm Nope
namespace Drat  class Nope: public Hmm::Oops  void f ()  j = 1;  ; 

在最后一行,“Hmm:Oops”是一个编译错误。预处理器将其更改为 Nope::Oops,但 Nope 已经是一个类名。

【讨论】:

什么#define?也许您的答案是指该问题的先前版本?【参考方案5】:

命名空间别名是一种通过不同的较短名称来引用长命名空间名称的便捷方式。

例如,假设您想使用 Boost 的 uBLAS 中的数字向量,而无需 using namespace 指令。每次都说明完整的命名空间很麻烦:

boost::numeric::ublas::vector<double> v;

相反,您可以为boost::numeric::ublas 定义一个别名——假设我们想将其缩写为ublas

namespace ublas = boost::numeric::ublas;


ublas::vector<double> v;

【讨论】:

为了解释反对意见,SO 不是也永远不会替代一本好的 C++ 教科书。任何这样的书都会回答你提出的问题。并且不应该使用回答您自己问题的 SO“功能”来提供此类书籍的释义。 没有冒犯...只是为了解释我这样做的原因:根据我在播客中 Joel 的 cmets 的理解,即使是“入门级”问题在 SO 上也是公平的游戏,而且它是如果该内容尚未以可访问的形式出现在 SO 上,可以提出问题并自行回答。但显然,这是不受欢迎的? 回答你自己的问题当然有一种礼仪,以避免激怒;在这种情况下,很明显它从来不是一个真正的问题。例如,***.com/questions/494927/… @Martin B:我不同意这是一个入门级问题——事实上,过去有很多更明显的问题,现在有很多投票。话虽如此,人们可能会觉得你只是想为自己赢得声誉。解决此问题的一种方法是将问题/答案中的一个或两个标记为“社区维基”。就个人而言,我会像您一样提出问题,并以社区的形式回答。如果问题有可取之处,那么您将获得投资回报率。 我认为重要的问题是这个问题是否真实”——这是你被问到的问题吗?是人们想知道的问题吗?是不是还没有被问到的问题并回答了 SO?如果您阅读了关于 R 社区在此处发布和回答问题的 SO 博客文章,请注意他们选择了他们的社区实际上一直在问的前 X 个问题,因此它具有真实世界相关性。随机获取特定语言知识的 sn-ps 并将它们发布在这里似乎没那么有用。

以上是关于在 C++ 中,啥是“命名空间别名”?的主要内容,如果未能解决你的问题,请参考以下文章

整个类范围内的 C++ 命名空间别名

BackSlash(\),PHP 中命名空间别名中的命名空间分隔符

小白学习C++ 教程十三C++命名空间namespace

命名空间

C# 命名空间别名 - 有啥意义?

C#中的#代表啥?