"using namespace Bar" 和 "using Bar::Foo" 有什么区别?

What is the difference between "using namespace Bar" and "using Bar::Foo"?

我有代码:

#include <iostream>

class Foo {

};

namespace Bar {
    struct Foo {

    };
}

namespace Baz
{
    void baz(const Foo &)
    {
        std::cout << "Hello";
    }
}

int main()
{
    Baz::baz(Bar::Foo());
}

编译器无法确定要使用哪个 Foo 并产生错误:

main.cpp: In function 'int main()':
main.cpp:23:19: error: invalid initialization of reference of type 'const Foo&' from expression of type 'Bar::Foo'
   23 |     Baz::baz(Bar::Foo());
      |                   ^~~~~
main.cpp:15:14: note: in passing argument 1 of 'void Baz::baz(const Foo&)'
   15 |     void baz(const Foo &)
      |   

Online compiler


当然,最简单的解决方案是使用 ::Foo::Baz::Foo,但我想用 O(1) 行代码解决所有可能的歧义。

我的第一个想法是 using namespace BarBaz 命名空间内:

namespace Baz
{
using namespace Baz;
//...

using-declaration: makes the symbol name from the namespace ns_name accessible for unqualified lookup as if declared in the same class scope, block scope, or namespace as where this using-declaration appears.

我希望所有 Bar 名称都成为 Baz 命名空间的一部分,并且非限定查找更喜欢 Baz::Foo。但由于某种原因它不起作用

Online compiler


但是 using Bar::Foo; 反过来又可以解决问题。这让我更加困惑

namespace Baz
{
    using Bar::Foo;

Online compiler


所以,我的问题是:在这种情况下,using namespace Barusing Bar::Foo 有什么区别?

using namespace Bar::Foo 会假定 Bar::Foo 是一个 命名空间 并将该命名空间中的所有内容导入当前范围, 例如

namespace Bar { namespace Foo { ... all names from this namespace would be imported ... } }

using Bar::Foo 会将 class Bar::Foo 导入范围:

namespace Bar { class Foo {...} }

并且如果您在 class Bar 嵌套了 class Foo 并且想要在不使用 class 说明符,那么使用看起来像:

class Bar {
  public:
    class Foo {};
};

using Foo = Bar::Foo;
// ...
// ... use Foo instead of Bar::Foo ...

cppreference是你的朋友。

关于using namespace ns_name;,它是

using-directive: From the point of view of unqualified name lookup of any name after a using-directive and until the end of the scope in which it appears, every name from ns_name is visible as if it were declared in the nearest enclosing namespace which contains both the using-directive and ns_name.

至于using ns_name::name;,它是

using-declaration: makes the symbol name from the namespace ns_name accessible for unqualified lookup as if declared in the same class scope, block scope, or namespace as where this using-declaration appears.

看似复杂,其实不然。此外,学习以这种方式解释的东西(我会说这接近于标准语)在深入 C++ 的深度时得到回报。