【问题标题】:What is the difference between "using namespace Bar" and "using Bar::Foo"?“使用命名空间 Bar”和“使用 Bar::Foo”有什么区别?
【发布时间】:2021-04-24 14:57:48
【问题描述】:

我有代码:

#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:使命名空间 ns_name 中的符号名称可访问以进行非限定查找,就好像在与该 using-declaration 出现的位置相同的类范围、块范围或命名空间中声明。

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

Online compiler


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

namespace Baz
{
    using Bar::Foo;

Online compiler


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

【问题讨论】:

    标签: c++ name-lookup


    【解决方案1】:

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

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

    using Bar::Foo 会将 类 Bar::Foo 导入作用域:

    namespace Bar { class Foo {...} }
    

    如果您在 class Bar 中有 nested class Foo 并且想在没有类说明符的情况下使用它,那么使用如下所示:

    class Bar {
      public:
        class Foo {};
    };
    
    using Foo = Bar::Foo;
    // ...
    // ... use Foo instead of Bar::Foo ...
    

    【讨论】:

    • 糟糕,我的错。我的意思是using namespace Bar
    【解决方案2】:

    cppreference 是你的朋友。

    关于using namespace ns_name;,它显示

    using-directive:从 using 指令之后的任何名称的非限定 name lookup 的角度来看,直到它出现的范围结束,来自 ns_name 的每个名称都是可见的就好像它是在最近的封闭命名空间中声明的,其中包含使用指令和 ns_name

    关于using ns_name::name;,它显示

    using-declaration:使 unqualified lookup 可以访问命名空间 ns_name 中的符号 name,就像在与 where 相同的类范围、块范围或命名空间中声明一样出现这个 using 声明。

    看起来很复杂,其实不然。此外,学习以这种方式解释的东西(我会说这接近标准语言)在深入了解 C++ 时会有所回报。

    【讨论】:

    • 现在我明白了。 最近相同。在这种情况下,最近 == 全局
    猜你喜欢
    • 2017-06-23
    • 1970-01-01
    • 2015-10-26
    • 2019-07-09
    • 1970-01-01
    • 2018-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多