在 C++ 中,您/尤其是/必须仔细阅读编译器错误消息。
请注意,第一个错误是“错误:‘A’不是命名空间名称”。确实如此,A 是一个类名。
using namespace Foo; // brings in all of foo;
using Bar::Baz // brings in only Baz from Bar
你想写:
using Test::A;
这有两个好处:它引入了 A 供你使用,并且它没有引入 Test 的所有其余部分,这也很好,因为你应该只引入你需要的内容,以免意外依赖你没有意识到你所依赖的东西。
但是,由于 foo 在 A 中是静态的,因此您仍然必须显式引用 A::foo 。 (除非你做了一些事情,比如编写一个转发到 A::foo 的自由函数;一般来说,如果你只是为了节省一些打字,那么这是一个坏主意。)
有些人可能建议根本不使用 using 声明,而是完全限定所有名称。
但这是(引用 Stroustrup 的话)“乏味且容易出错”,并且它妨碍了重构:假设您完全限定了 FooMatic::Stack 类的每次使用,然后管理层坚持要求,就在您准备这样做之前去生产,你使用 BarMatic 非常相似的 Stack 类,因为 barMatic 刚刚买下了你的公司。
如果您在所有地方都完全合格,您将进行大量的 grep 操作,希望您的正则表达式是正确的。如果您使用了 using 声明,则只需修复您的(希望是共享的)头文件即可。这样,using 声明很像“typedef int ourInt;”或一个明显的常量或 const:“const int FOO = 1;”,因为它提供了一个位置来更改引用到多个位置的内容。在每次使用时完全限定命名空间会消除这一好处。
相反,如果您使用 using 指令并引入所有命名空间 FooMatic,那么您的 grep 可能会更加困难,如果说管理层坚持使用 BarMatic::Foo 但您仍然必须使用 FooMatic:Baz,BarMatic 相当于 Baz 的无论什么原因都无法使用。
因此,一次引入一种类型(类、函数、常量)通常是最灵活的,这是最好的保护自己免受不可避免但未知的变化的方法。与大多数编码一样,您希望最大限度地减少繁琐的重复,同时保持足够的粒度。