如何访问命名空间内嵌未命名命名空间变量?

5

这个问题已经在链接unnamed namespace within named namespace中讨论过,但是没有提供完美的答案来解决如何访问嵌套在命名空间下的未命名命名空间的变量,如果两个变量都相同。

考虑这段代码:

namespace apple {   
    namespace {
                 int a=10;
                 int b=10;
              }
   int a=20;
}


int main()
{
cout<<apple::b; //prints 10
cout<<apple::a; // prints 20
}

未命名的命名空间中的变量"a"始终是隐藏的。如何访问未命名命名空间中的变量"a"

在命名的命名空间内声明未命名的命名空间是否合法?


这个链接有点帮助...虽然没有明确的答案。 - blake
@secretgenes 嗯,答案可能是:实际上做不到你想要的,但编写那段代码是合法的。 - user0042
@user0042:那么你应该解释一下为什么不这样做!! - secretgenes
@secretgenes 好的,我全力以赴。需要进行更多的研究。 - user0042
2个回答

1

未命名的命名空间中的变量 "a" 总是被隐藏的。如何访问未命名命名空间中的 "a" 变量?

看起来你不能在封闭的命名空间之外限定未命名的命名空间。

好吧,以下是解决歧义的方法:

namespace apple {   
    namespace {
        int a=10;
    }

    int getPrivateA() {
        return a;
    }

    int a=20;
}

int main() {
    cout<<apple::getPrivateA() << endl;
    cout<<apple::a << endl;
}

请看在线演示

虽然我知道这并没有完全回答你的问题(除了是否可以在另一个命名空间中嵌套未命名的命名空间是合法的)
但我需要更深入地研究 c++标准规范 的第3.4章和第7.3章,才能给你一个明确的答案,解释为什么你想做的事情是不可能的。


我知道可以通过在命名空间中创建不同的函数名称来访问它,但如果函数名称也相同怎么办?这是访问未命名命名空间变量的解决方法。如果没有访问它的方法,那么难道不应该有一个警告或错误消息表明它是无法访问的吗?因为它没有任何作用。 - secretgenes
@secretgenes 并非所有的_shadowing_情况都会引发警告。而且这是编译器实现特定的。为什么你要给这些(假设的)函数取相同的名称呢? - user0042
未命名的命名空间有其自己的作用域,因此可能会给两个函数赋予相同的名称。如果我必须定义函数来访问未命名命名空间变量,那么我可以单独完成它,而无需使用嵌套的未命名命名空间(通过在“getPrivateA函数”内声明int a)。在这种情况下,未命名的命名空间没有用处。 - secretgenes

0

我前几天看到了这篇文章,对于“如何访问未命名命名空间中的变量a?”我有一个答案。

我回答这个问题时完全知道这不是一个完美的答案,但这是一种访问未命名命名空间中的“a”的方法。

#include <iostream>
#include <stdio.h>

namespace apple {
        namespace {
                     int a=257;
                     int b=10;
                  }
       int a=20;
    }

using namespace std;

int main() {

int* theForgottenA;

// pointer arithmetic would need to be more modified if the variable before 
// apple::b was of a different type, but since both are int then it works here to subtract 1
theForgottenA = &apple::b - 1; 

cout << *theForgottenA; //output is 257

}

1
这是事实,但它是一种hack(c++中的缺陷),你甚至可以访问类的所有私有成员。 - secretgenes
是的,指针算术确实很棒。无论如何,我在思考你的问题,并认为我应该补充一下,这在技术上是一种访问它的方式。 - 9Breaker
2
虽然这可能适用于所有的C++编译器,但是a在b之前的事实并不是你应该期望的...还有一些人会进行编辑而不知道它们应该保持在一起...在你的代码中使用这样的技巧并不是一个好主意。 - Alexis Wilke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接